블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2737)
Unity3D (817)
Script (91)
Extensions (14)
Effect (3)
NGUI (77)
UGUI (8)
Physics (2)
Shader (36)
Math (1)
Design Pattern (2)
Xml (1)
Tips (200)
Link (22)
World (1)
AssetBundle (25)
Mecanim (2)
Plugins (70)
Trouble Shooting (68)
Encrypt (7)
LightMap (4)
Shadow (4)
Editor (8)
Crash Report (3)
Utility (9)
UnityVS (2)
Facebook SDK (2)
iTween (3)
Font (11)
Ad (14)
Photon (2)
IAP (1)
Google (8)
Android (45)
iOS (41)
Programming (474)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (228)
협업 (58)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (53)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
04-20 00:00

[출처] www.raywenderlich.com/9671886-new-unity-input-system-getting-started

 

New Unity Input System: Getting Started

In this Unity Input System tutorial, you’ll learn how to convert player input in your existing projects from the old Input Manager to the new Input System.

www.raywenderlich.com

 

In this Unity Input System tutorial, you’ll learn how to convert player input in your existing projects from the old Input Manager to the new Input System.

 

Version

  • C# 7.3, Unity 2020.1, Unity

Handling input is a pillar of creating a successful game. Input devices help player characters perform actions inside the game such as walking, jumping and climbing.

Recently, many new platforms have come out, introducing more Unity input devices. These include touch screens, VR controllers and gamepads from different game consoles. If you want your game to support different platforms, you need to write code to handle the logic for different devices. The more platforms you support, the more complex your code will be.

Luckily, there’s a new Unity Input System that helps developers deal with this situation, making input-related code easier to manage.

In this tutorial, you’ll learn:

  • The features of the new Input System.
  • How the new system works.
  • How to migrate apps to the new Input System from the old Input Manager.

The materials for this tutorial were built in Unity version 2020.1. You can get this version of Unity from the Unity website or install it with the Unity Hub.

Note: Although this tutorial is for beginners, you’ll need to have some basic knowledge of Unity development and how to work with Unity Editor to complete it. If you’re new to Unity development, check out our tutorial on Getting Started In Unity.

Getting Started

First, download the starter project for this tutorial using the Download Materials button at the top or bottom of this page. Unzip its contents and open NewUnityInputSystem-Starter in Unity.

After the project loads, you’ll see the RW folder in the Project Window:

Take a look at the organization of the folder:

  • Fonts: Fonts used in the scene.
  • Materials: Materials for the scene.
  • Models: 3D meshes for the player character and game environments.
  • Prefabs: Pre-built components composed of Scripts and Models.
  • Scenes: The game scene.
  • Scripts: Scripts with game logic.
  • Settings: The settings file, which is where you’ll put the input settings.
  • Shaders: Shaders for special effects like the player’s shadow.
  • Textures: The graphics used by Materials and UIs.

The starter project is a simple platformer game. You control the player character by moving around and jumping to collect coins.

The game is ready to play. Open GameScene from the Scenes folder and click Play to try the game for yourself!

Currently, the Move and Jump controls use the old Unity Input Manager. You’ll learn how to use the new Input System to replace the old system later in the tutorial.

What’s New in the Unity Input System

Before diving into the code, take a look at the new Input System’s features.

Simpler Action and Binding Architecture

The old input system checked input from different devices every frame to determine whether players took an action.

The following code, which supports both gamepads and keyboards, is an example of the old way of doing things:

bool isGamepad = Input.GetAxis("Gamepad Fire") != 0f; if (isGamepad) { return Input.GetAxis("Gamepad Fire") >= triggerAxisThreshold; } else { return Input.GetButton("Fire"); }

The code uses if-else branching to handle support for different devices and their associated actions.

The new Input System separates device input from code actions. That means you only have to handle the actions the players trigger. You don’t need to know which device the player is using or which button they’re clicking.

An input event in the new system is called an action, while the mapping between an action and an input device is a binding.

Gathering Information With the Input Debug Tool

The Input System provides you with a new tool called Input Debugger. Open it by selecting Window ▸ Analysis ▸ Input Debugger from the menu.

The Input Debugger helps developers by gathering the following information in one place:

The state of the Input System, including:

  • Device: Information about the connected devices.
  • Layout: Which controls those devices provide.
  • Setting: The configuration of the input system.

It also provides real-time information about a specific device. Open this by double-clicking the device from the device list in the Input Debugger window.

Here’s a demo of the Input Debugger in action:

Feel free to keep the Input Debugger open while you work through the tutorial.

Support for Multiple Devices and Platforms

With the increased flexibility from the Input System’s new architecture, Unity can support many different input devices, including:

  • Keyboard
  • Mouse
  • Pen
  • TouchScreen
  • Sensor
  • Joystick
  • GamePad

Note: The Input System also supports devices that implement the USB HID specification. For more details, check out Unity’s Supported Devices Documentation.

Understanding the New Input System

The new Input System has four building blocks that funnel events from player devices to your game code:

  • Input Action Assets: A settings file that contains the properties of the actions and their associated bindings.
  • Actions: Actions define the logical meanings of the input. You can find that information in the Input Action Assets.
  • Bindings: Bindings describe the connection between an action and the input device controls. You’ll find this information in the Input Action Assets, too.
  • PlayerInput: PlayerInput is a script that manages and links action events to the corresponding code logic.

Sometimes it’s easier to understand a new workflow if you can visualize it, so take a look at the image below:

Break this down into its simplest steps:

  • First, the Unity Engine collects information from the connected devices and sends corresponding events, like a button click, to the Input System.
  • The Input System then translates those events into actions, based on the action and binding information stored in the Input Action Assets.
  • It then passes the actions to the PlayerInput script, which invokes the corresponding methods.

Now that you know a little more about how the Input System works, you’ll use it to control the game character in the coming sections.

Installing the New Input System

The first thing you’ll do is install the new Input System package. The standard Unity installation doesn’t include it.

Open Window ▸ Package Manager in the menu bar. Make sure that you select Unity Registry in the Packages dropdown, if you haven’t already.

Find Input System on the list. Select it and click Install.

Creating an Input Action Asset

Once you’ve installed the Input System package, you’ll create an Input Action Asset to store the settings for your actions and bindings.

Open the Project window and select Settings from RW. Right-click, select Create ▸ Input Actions and rename it to MyControl.

Setting up the Action Editor

Double-click MyControl in Settings to open the Action Editor, which helps you manipulate actions and control bindings.

Since this is a new window, take a look at the sections:

  1. Action Maps: Groups of actions that occur in the game. You can group actions for different purposes, like player, gameplay or UI.
  2. Actions: The list of actions and bindings associated with the selected Action Map. In this panel, you create, modify or delete actions and bindings.
  3. Properties: Edit the action or binding properties in this panel, such the type of action and the controls you associated with the binding.
  4. Save Assets: This is a very important function: You must click Save Asset after making any changes to the Input Action Asset. If you forget to save, the setting won’t work. Thus, you won’t see the expected result and may think there’s a bug in the code.

    You can switch on Auto Save to prevent the problem, but it’s quite slow.

Now you’re ready to create your first action, the Jump action.

Creating a Jump Action

First, open the Action Editor and click the + icon in the ActionMap to create a new Action Map. Rename it from the default, New Action Map, to Player.

Then, in the Action panel, double-click New Action and rename it to a meaningful name: Jump.

Finally, you need to add a binding to the Jump action. You’ll bind the Spacebar and Left Mouse Button to this action by following these steps:

  1. Select the Jump action, click the + icon and select Add Binding.
  2. Click the new binding item, <No binding>.
  3. Click the Path field in the Binding properties panel.
  4. Type Spacebar Keyboard and select Space [Keyboard] to create the binding for the Spacebar.
  5. Repeat steps 1–3 to create another binding for the Left Mouse Button.
  6. Type Left Button in the Path field and select Left Button [Mouse] to create the binding.

Congratulations, you’ve now associated the Jump action with the Spacebar on the keyboard and the left button on the mouse.

Now to hook up those actions with your code!

Implementing the Jump Logic

First of all, you need to remove the old input logic from the project. Open Player.cs and navigate to the Update() method.

void Update() { UpdateAnimation(); if (!jumping && Input.GetKeyDown(KeyCode.Space)) { HandleJump(); } }

As you can see, the current code triggers the animation updates, then it checks if the player has pressed the space bar in order to start a jump.

Now that the Jump action and its control bindings are ready, the next thing to do is link the action to the code.

Linking the Jump Action to the Code

Start by deleting the code in Update to remove the implementation of the old Input Manager so you can add Jump logic using the new Input System. Update will now only control the animations.

void Update() { UpdateAnimation(); }

Save the script and go back to the editor. Select the Player object in the Hierarchy and add a PlayerInput component from the Inspector.

Next, you’ll drag MyControl to PlayerInput’s Actions. Make sure to set the Default Map to Player.

Finally, open Player.cs and add a new method called OnJump() with the following code:

public void OnJump() { HandleJump(); }

You’ve associated this method with the Jump action by using this pattern to name it: public void On[Action Name Goes Here]().

For example, the Jump action invokes OnJump(), while the Attack action invokes OnAttack().

Click Save Asset in the Action Editor and run the game. Now you can use the SpaceBar or the left mouse button to make the player character jump. It’s really that easy!

Creating the Move Action

You’ve learned how to use the Input System to create a Jump action. Next up is the Move action! Move is similar to Jump, but it has a few key differences.

For example, the Jump action is a simple trigger event, while the Move action is an event that carries values: the movement direction, which comes from user input.

Again, you need to create the action and its binding. Start by going to Action Editor (double click MyControl if you lost the window) and click the + icon in the Actions panel to create a new action. Rename it to Move.

Next, open the Action properties panel, change Action Type to Value and Control Type to Vector 2.

Finally, remove <No Binding> by right-clicking and selecting Delete.

Now, you need to create the Move action’s bindings.

First, you’ll click the + icon in the header of the Move action. Then, select Add 2D Vector Composite, which will create four binding items corresponding to the up, down, left and right directions.

Now, you’ll set the path of each binding as follows:

  • Up: Up Arrow [Keyboard]
  • Down: Down Arrow [Keyboard]
  • Left: Left Arrow [Keyboard]
  • Right: Right Arrow [Keyboard]

Don’t forget to save the asset in the Action Editor!

Implementing the Move Logic

Before adding new movement logic, you need to remove the implementation of the old Unity input.

Open Player.cs and go to FixedUpdate():

private void FixedUpdate() { // 1 float speedX = Input.GetAxisRaw("Horizontal"); // Left, Right float speedY = Input.GetAxisRaw("Vertical"); // Back, Forward moveVec = new Vector3(speedX, 0, speedY); if (jumping == false) { // 2 UpdateWhenGrounded(); } else { // 3 UpdateWhenJumping(); } }

Note that FixedUpdate() is called in every fixed frame-rate frame.

Now, break this down:

  1. Input.GetAxisRaw returns the value of Axis. Input.GetAxisRaw("Horizontal") gives the value of the X-Axis, while Input.GetAxisRaw("Vertical") gives the value of Y-Axis.

    These two values define the movement vector moveVec, which you use to control the direction of the player movement.

  2. The logic of the player character’s behavior while it’s on the ground.
  3. The logic of the player character’s behavior while it’s jumping.

Now, delete all the code prior to the if statement to remove the old input logic. Add the following code above the class definition:

using UnityEngine.InputSystem;

This allows you to access values from the new Input System.

Then, add OnMove(), which the Move action invokes.

public void OnMove(InputValue input) { Vector2 inputVec = input.Get<Vector2>(); moveVec = new Vector3(inputVec.x, 0, inputVec.y); }

When a player presses the Up, Down, Left or Right keys, it passes a Move action to this method, along with the values. Here’s how the key presses affect the values:

  • Up: (0, 1)
  • Down: (0, -1)
  • Left: (-1, 0)
  • Right: (1, 0)
  • No Key: (0, 0)
  • Up and Left: (1, -1)

InputValue is a new type you may not know. This class has a Get\() method that you can use to access its values. In this instance, you want the 2D Vector Composite you set in the binding to calculate the movement vector.

Click Play to test the logic.

Handling Actions

The new Input System provides four ways to handle action events.

In this tutorial, you used the SendMessages approach. You can change this option in the Behavior field in the PlayerInput component.

SendMessage and BroadcastMessage are the simplest ways to handle actions. When you use these two options, the system invokes the method with a name matching the name of the action.

For example, in this tutorial, the Jump action invokes OnJump() and the Move action invokes OnMove().

BroadcastMessage is similar to SendMessage, except it can invoke the methods on any child GameObject. These two options are easy to use because you don’t need to configure anything to use them.

Using Invoke Unity Events

When using Invoke Unity Events, you configure the action much as you’d configure a button click in Unity UI.

This approach is more flexible, letting you use different methods in different objects. Those GameObjects don’t even need to have the PlayerInput component.

Using Invoke C# Events

This approach is as flexible as Invoke Unity Events. You can define the methods you want to use instead of using methods with a specific name. However, if you use this approach, you need to write code to control which methods to invoke.

Here is a sample of how this looks:

private void Awake() { animator = GetComponentInChildren<Animator>(); rigidbody = GetComponent<Rigidbody>(); // 1 GetComponent<PlayerInput>().onActionTriggered += HandleAction; } private void HandleAction(InputAction.CallbackContext context) { // 2 if(context.action.name == "Jump") { HandleJump(); } }

Here’s what this code does:

  1. Gets the PlayerInput component and registers the method to onActionTriggered.
  2. Controls which method to call for different actions.

Using the Update Cycle of the New Input System

In the old Unity Input Manager, you checked the input in every frame using Update(). In the new Input System, you may wonder when actions are being sent, and if they’re sent before every Update().

The new Input System uses a different update cycle that’s independent of MonoBehaviour‘s lifecycle. You can read more about it in Unity’s Execution Order documentation.

The system offers three Update Modes to control the update cycle. You can configure them in Project Settings ▸ Input System Package ▸ Update Mode.

Take a look at each of these nodes:

  • Dynamic Update: Processes events at irregular intervals determined by the current frame rate. This is the default setting.
  • Fixed Update: Processes events at fixed-length intervals. Time.fixedDeltaTime determines the length of the interval.
  • Manually: Events aren’t processed automatically; you process them when you call InputSystem.Update(). If you want a check similar to the old system, you can call InputSystem.Update() in Update().

These new options, as part of the new Input System, give you a lot more control over input, whilst also making it easier to support multiple input devices :]

Where to Go from Here?

Download the completed project using the Download Materials button at the top or bottom of this tutorial.

In this Unity Input tutorial, you’ve learned:

  • The basic layout of the new Input System.
  • How to use actions and bindings.
  • How to handle different kinds of player input efficiently.

To test your skill, try to add a Pause action to the game!

To learn more about the new Input System, you can read the Unity Input System manual.

I hope you have enjoyed this tutorial! If you have any questions or comments, please join the forum discussion below.

반응형
Posted by blueasa
, |

유니티 데이터 통신 압축용으로 사용 중.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.BZip2;

public class ZipHelper
{
    public static byte[] Zip(byte[] data)
    {
        return Zip(data, 0, data.Length);
    }

    public static byte[] Unzip(byte[] data)
    {
        return Unzip(data, 0, data.Length);
    }

    public static byte[] Zip(byte[] data, int offset, int size)
    {
        MemoryStream inStream = new MemoryStream(data, offset, size);
        MemoryStream outStream = new MemoryStream();
        BZip2.Compress(inStream, outStream, false, 3);

        byte[] result = outStream.ToArray();
        inStream.Close();
        outStream.Close();

        return result;
    }

    public static byte[] Unzip(byte[] data, int offset, int size)
    {
        MemoryStream inStream = new MemoryStream(data, offset, size);
        MemoryStream outStream = new MemoryStream();
        BZip2.Decompress(inStream, outStream, false);

        byte[] result = outStream.ToArray();
        inStream.Close();
        outStream.Close();

        return result;
    }
}

// 예제
//class Program
//{
//    static void Main(string[] args)
//    {

//        byte[] array = new byte[1000];
//        for (int i = 0; i < array.Length; i++)
//        {
//            array[i] = (byte)(i % 255);
//        }
//        byte[] compress = ZipHelper.Zip(array);
//        byte[] decompress = ZipHelper.Unzip(array);


//    }

//}

 

 

[SharpZip dll 다운로드] https://www.nuget.org/packages/SharpZipLib/

 

[참조] https://nahyungmin.tistory.com/38

반응형
Posted by blueasa
, |

 

[링크] slee16.blog.me/221706003164

 

Tip : Unity 자이로 & 가속도 센서 관련

​기기의 기울기를 사용하는 게임제작 외주를 하고 있는데, 분명 나온지 오래된 기능이고 많이 사용했을 것...

blog.naver.com

 

반응형
Posted by blueasa
, |
    /// <summary>
    /// 회전 없이 유도 이동만 하는 함수
    /// </summary>
    /// <param name="_trTarget">목표 지점</param>
    /// <param name="_v3CurrentDirection">현재 오브젝트가 이동할 방향</param>
    /// <returns></returns>
    IEnumerator Move_Guided(Transform _trTarget, Vector3 _v3CurrentDirection)
    {
        Transform trTarget = _trTarget;
        Vector3 v3TargetDirection = (trTarget.position - this.transform.position).normalized;
        Vector3 v3CurrentDirection = _v3CurrentDirection;
        if (v3CurrentDirection == Vector3.zero)
        {
            v3CurrentDirection = v3TargetDirection;
        }

        float fLookSpeed = 7f;
        float fMoveSpeed = 50f;
        float fAccumTime = 0f;

        while (0.01f < (this.transform.position - trTarget.position).sqrMagnitude)
        {
            // Rotate
            v3TargetDirection = (trTarget.position - this.transform.position).normalized;
            v3CurrentDirection = Vector3.RotateTowards(v3CurrentDirection, v3TargetDirection, Time.deltaTime * fLookSpeed, 0f);
            v3CurrentDirection = v3CurrentDirection.normalized;
            // Translate
            fAccumTime += Time.deltaTime * fMoveSpeed;
            this.transform.localPosition += (v3CurrentDirection * fAccumTime);
            yield return null;
        }

        yield return null;
        
        // 도착했으면 Destroy or Recycle
    }

 

보통 유도 기능 만들때 오브젝트 자체를 회전시키고, transform.forward 방향으로 Translate만 하면 됐는데

 

이번에는 유도 기능으로 이동만 하고 회전하지 않게 하기 위해서

Direction Vector를 따로 두고 Vector3.RotateTowards()를 사용해서 이동하게 만들었다.

 

P.s. 적당히 테스트 한거니 더 이쁘게 만들고 싶은분은 직접 수정 및 테스트 해보세요.

 

[참조] https://docs.unity3d.com/ScriptReference/Vector3.RotateTowards.html

반응형
Posted by blueasa
, |
        // AndroidManifext.xml
        // <meta-data android:name="aa.bb.channelid" android:value="D4LW023" />
        // <meta-data android:name="aa.bb.subchannelid" android:value="1" />
        AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
        string packageName = activity.Call<string>("getPackageName");
        AndroidJavaObject manager = activity.Call<AndroidJavaObject>("getPackageManager");
        AndroidJavaObject packageInfo = manager.Call<AndroidJavaObject>("getApplicationInfo", packageName, manager.GetStatic<int>("GET_META_DATA"));
        AndroidJavaObject aBundle = packageInfo.Get<AndroidJavaObject>("metaData");
        
        string strChannelId = aBundle.Call<string>("getString", "aa.bb.channelid");	// string
        int iSubChannelId = aBundle.Call<int>("getInt", "aa.bb.subchannelid");	// int

 

[정보제공] 게임코디-선후님

반응형
Posted by blueasa
, |
if (animator.GetCurrentAnimatorStateInfo(0).IsName("YourAnimationName"))
{
    // do your magic
}

 

[출처] https://stackoverflow.com/questions/23449494/is-there-an-isplaying-type-function-for-animator

 

Is there an isPlaying() type function for Animator

I know you can do animation.isPlaying() but is there something similiar for Animator ? So if I have: Animator animator; void Start() { animator = GetComponenet(); } Then I c...

stackoverflow.com

 

반응형
Posted by blueasa
, |

hello,

From that post : http://forum.unity3d.com/threads/how-can-you-add-items-to-the-xcode-project-targets-info-plist-using-the-xcodeapi.330574/ by modifying a bit the script i got that :

     [PostProcessBuild]
     public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject) 
     {  
         if (buildTarget == BuildTarget.iOS) 
         {
             // Get plist
             string plistPath = pathToBuiltProject + "/Info.plist";
             PlistDocument plist = new PlistDocument();
             plist.ReadFromString(File.ReadAllText(plistPath));
             
             // Get root
             PlistElementDict rootDict = plist.root;
             
             // Change value of CFBundleVersion in Xcode plist
             var buildKey = "UIBackgroundModes";
             rootDict.CreateArray (buildKey).AddString ("remote-notification");
             
             // Write to file
             File.WriteAllText(plistPath, plist.WriteToString());
         }
     }

 

i just did it, it seems to work, need further test though.

Edit : Note that the script should be in Assets/Editor folder. Edit 2 : i created i string it should be a array, i changed the code.

 

[출처] https://answers.unity.com/questions/1066927/postprocessing-ios-activate-background-mode-for-pu.html

 

PostProcessing iOS Activate Background Mode for Push Notifications - Unity Answers

 

answers.unity.com

 

반응형
Posted by blueasa
, |

[사용도구]

Unity 5.6.7

Xcode 10.2.1

 

최근 iOS빌드에서 XCode-Capabilities-Push Notifications를 수동으로 ON 시켜야 되는 문제가 귀찮아서 자동으로 하는 방법을 찾아보고 정리해둠.

(유니티 5.x에서 되는 방법을 찾느라 이래저래 삽질을..)

 

[순서]

1) https://bitbucket.org/Unity-Technologies/xcodeapi 소스 다운로드.

 

2) 다운로드 받은 소스를 유니티 해당 프로젝트의 Editor 폴더 아래 추가

   나의 경우는 ../Assets/Editor/XCodeApi 아래에 추가. 

   2-1) Xcode.Tests는 에러나서 제거 함.(2017 이후 버전 API를 사용하는 듯 함)

 

3) iOS PostProcessBuild 소스에 PBXCapabilityType.PushNotifications 추가(AddCapability)

using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.iOS.Xcode;
using UnityEditor.Callbacks;
using System.Collections;

public class XCodeSettingsPostProcesser
{

    [PostProcessBuild]
    public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuiltProject)
    {
        // Stop processing if targe is NOT iOS
        if (buildTarget != BuildTarget.iOS)
        {
            return;
        }

            /// Initialize PbxProject
            var projectPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
            PBXProject pbxProject = new PBXProject();
            pbxProject.ReadFromFile(projectPath);
            // Unity 2019 대응
#if UNITY_2019_3_OR_NEWER
            //string targetGuid = pbxProject.GetUnityFrameworkTargetGuid();
            string strMainTargetGuid = pbxProject.GetUnityMainTargetGuid();
            string strFrameworkTargetGuid = pbxProject.GetUnityFrameworkTargetGuid();
#else
            string targetGuid = pbxProject.TargetGuidByName("Unity-iPhone");
#endif

        // Add push notifications as a capability on the target
        pbxProject.AddCapability(targetGuid, UnityEditor.iOS.Xcode.Custom.PBXCapabilityType.PushNotifications);

        // Apply settings
        File.WriteAllText(projectPath, pbxProject.WriteToString());
    }
}

    3-1) 주의사항

         기존 PBXProjectUnityEditor.iOS.Xcode.PBXProject인데, 추가 된 플러그인을 사용하기 위해 UnityEditor.iOS.Xcode.Custom.PBXProject로 변경필요.

         예1) UnityEditor.iOS.Xcode.PBXProject -> UnityEditor.iOS.Xcode.Custom.PBXProject

         예2) UnityEditor.iOS.Xcode.PBXCapabilityType -> UnityEditor.iOS.Xcode.Custom.PBXCapabilityType

 

4) entitlements 생성을 위해 아래 클래스를 Editor 폴더에 추가

    (entitlements 파일 내용을 스크립트 내부에 넣어서 생성해서 별도의 파일 추가를 안해도 돼서 편한 듯)

using UnityEditor;
 using UnityEditor.Callbacks;
 using UnityEngine;
 using System.IO;
 using UnityEditor.iOS.Xcode;
 
 public class EntitlementsPostProcess
 {
     private const string entitlements = @"
     <?xml version=""1.0"" encoding=""UTF-8\""?>
     <!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd"">
     <plist version=""1.0"">
         <dict>
             <key>aps-environment</key>
             <string>development</string>
         </dict>
     </plist>";
     
     [PostProcessBuild]
     public static void OnPostProcess(BuildTarget buildTarget, string buildPath)
     {
         if (buildTarget != BuildTarget.iOS) return;
 
         var file_name = "unity.entitlements";
         var proj_path = PBXProject.GetPBXProjectPath(buildPath);
         var proj = new PBXProject();
         proj.ReadFromFile(proj_path);
 
         // target_name = "Unity-iPhone"
         var target_name = PBXProject.GetUnityTargetName();
         var target_guid = proj.TargetGuidByName(target_name);        
         var dst = buildPath + "/" + target_name + "/" + file_name;
         try
         {
             File.WriteAllText(dst, entitlements);
             proj.AddFile(target_name + "/" + file_name, file_name);
             proj.AddBuildProperty(target_guid, "CODE_SIGN_ENTITLEMENTS", target_name + "/" + file_name);
             proj.WriteToFile(proj_path);
         }
         catch (IOException e)
         {
             Debug.LogWarning($"Could not copy entitlements. Probably already exists. ({e})");
         }
     }
 }

 

[1) 참조] https://bitbucket.org/Unity-Technologies/xcodeapi

 

Bitbucket

 

bitbucket.org

[3) 참조] https://qiita.com/fullcorder/items/b82c48022acd0b4ff957

 

Unity5のPostProcessBuildでXcode Capabilityの設定する方法 - Qiita

XcodeのCapabilityの各種設定を`PostProcessBuild`で行う方法です。 Pushの設定などを有効にするアレです。 # ざっくり流れ ### In-App Purchaseなどentitlementsフ...

qiita.com

[4) 참조] https://answers.unity.com/questions/1224123/enable-push-notification-in-xcode-project-by-defau.html

 

Enable Push Notification in XCode project by default? - Unity Answers

 

answers.unity.com

 

반응형
Posted by blueasa
, |

XcodeのCapabilityの各種設定をPostProcessBuildで行う方法です。
Pushの設定などを有効にするアレです。

ざっくり流れ

In-App Purchaseなどentitlementsファイルが不要なcapabilityの場合

  1. Unityのリポジトリから, 最新のXcode Manipulation API(以下Xcode API)を持ってくる
  2. 既存のプロジェクトにインポートできるように修正する
  3. 最新のAPIでPostProcessBuildのScriptを書く

iCloudなどentitlementsファイルが必要なcapabilityの場合

  1. 一旦先にビルドしてXcodeProjectを作成する
  2. capabilityを設定し, entitlementsファイルを作成する
  3. PostProcessBuildでentitlementsファイルとビルドプロパティを追加する
  4. 以後entitlements file不要な場合に合流する

詳細な流れ

entitlementsファイルのいらないcapabilityの場合

Unityのリポジトリから, 最新のXcode APIを持ってくる

  • リポジトリ内のXcodeフォルダをデスクトップなど作業環境にコピーします
  • ターミナルでXcodeディレクトリに移動し, 下記のコマンドでC#のソースコードのnamespaceを変更します.仮に変更後のnamespaceをUnity2017.iOS.Xcodeとします

 

$ pwd
Users/fullcorder/Desktop/Xcode 
$ find . -name '*.cs' | xargs sed -i "" 's/UnityEditor.iOS.Xcode/Unity2017.iOS.Xcode/g'

 

  • Xcode/Propertiesディレクトリをは不要なので削除します
  • UnityプロジェクトのEditorディレクトリにXcodeフォルダごとインポートします

PostProcessBuildスクリプトを作成し下記のようにPBXProject#AddCapabilityを使って追加します

Unity2017.1のリファレンス
https://docs.unity3d.com/2017.1/Documentation/ScriptReference/iOS.Xcode.PBXProject.AddCapability.html

 

[PostProcessBuild]
public static void AddCapability(BuildTarget buildTarget, string path)
{
    if(EditorUserBuildSettings.activeBuildTarget != BuildTarget.iOS)
    {
        return;
    }

    string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";

    var proj = new PBXProject();
    proj.ReadFromString(File.ReadAllText(projPath));

    string target = proj.TargetGuidByName(TargetGroup);

    proj.AddCapability(target, PBXCapabilityType.PushNotifications);
    proj.AddCapability(target, PBXCapabilityType.InAppPurchase);

    File.WriteAllText(projPath, proj.WriteToString());
}

 

  • 以上ですあとはビルドすればOKです

entitlementsファイルが必要なcapabilityの場合

entitlementsファイルが必要な場合は, entitlementsファイルを作成したものをPostProcessBuildで追加し、あとはentitlementsファイルが不要な場合に合流します

entitlementsファイルを作成

  • UnityでiOSビルドしてXcodeProjectを吐き出します
  • Capabilityタブに行き, Pushなどをこうなりたい状態, PostProcessBuild後で設定後の形にします
  • entitlementsファイルがXcodeプロジェクト内に作成されるので取り出してUnityProjectにインポートします
  • Unityフォーラムの下記ポストからEntitlementsPostProcess.csをDLしてUnityにインポートします

https://forum.unity3d.com/threads/how-to-put-ios-entitlements-file-in-a-unity-project.442277/

  • EntitlementsPostProcess.csのSerializeFieldであるEntitlements Fileにentitlementsファイルを設定します
  • 以上でentitlementsファイル追加が完了します

以後、前述の手順と合わせてビルドすると無事, 設定反映したになっていると思います
(Plist編集は別途スクリプト書いてください)

その他

Unity2017からは多分使えるAPIなので、長いプロジェクトの場合, プラットフォーム依存コンパイルでUnity5のみ限定して今回変更したnamespaceを使うようにすると良いと思います。

環境

macOS Sierra
Unity 5.5.3f1
Xcode 8.3.2

参考 
https://bitbucket.org/Unity-Technologies/xcodeapi
https://forum.unity3d.com/threads/how-to-put-ios-entitlements-file-in-a-unity-project.442277/

 

 

[출처] https://qiita.com/fullcorder/items/b82c48022acd0b4ff957

 

Unity5のPostProcessBuildでXcode Capabilityの設定する方法 - Qiita

XcodeのCapabilityの各種設定を`PostProcessBuild`で行う方法です。 Pushの設定などを有効にするアレです。 # ざっくり流れ ### In-App Purchaseなどentitlementsフ...

qiita.com

 

반응형
Posted by blueasa
, |

I manage to get it working by a C# script, but since this build setting need an .entitlementfile in your xcode project, first you will need to create a text file called [projectName].entitlement anywhere in your project with this content:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3. <plist version="1.0">
  4. <dict>
  5. <key>aps-environment</key>
  6. <string>development</string>
  7. </dict>
  8. </plist>

Now you can add this script on the Editor folder:

  1. using System.IO;
  2. using JetBrains.Annotations;
  3. using UnityEditor;
  4. using UnityEditor.Callbacks;
  5. using UnityEditor.iOS.Xcode;
  6. using UnityEngine;
  7.  
  8. public class PostProcessBuildScript : ScriptableObject
  9. {
  10. public DefaultAsset entitlementsFile;
  11.  
  12. [PostProcessBuild, UsedImplicitly]
  13. public static void ChangesToXcode(BuildTarget buildTarget, string pathToBuiltProject)
  14. {
  15. // Get project PBX file
  16. var projPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
  17. var proj = new PBXProject();
  18. proj.ReadFromString(File.ReadAllText(projPath));
  19. var target = proj.TargetGuidByName("Unity-iPhone");
  20.  
  21. // Create an instance of this ScriptableObject so we can point to its entitlements file
  22. var dummy = CreateInstance<PostProcessBuildScript>();
  23. var entitlementsFile = dummy.entitlementsFile;
  24. DestroyImmediate(dummy);
  25. if (entitlementsFile != null)
  26. {
  27. // Copy the entitlement file to the xcode project
  28. var entitlementPath = AssetDatabase.GetAssetPath(entitlementsFile);
  29. var entitlementFileName = Path.GetFileName(entitlementPath);
  30. var unityTarget = PBXProject.GetUnityTargetName();
  31. var relativeDestination = unityTarget + "/" + entitlementFileName;
  32. FileUtil.CopyFileOrDirectory(entitlementPath, pathToBuiltProject + "/" + relativeDestination);
  33.  
  34. // Add the pbx configs to include the entitlements files on the project
  35. proj.AddFile(relativeDestination, entitlementFileName);
  36. proj.AddBuildProperty(target, "CODE_SIGN_ENTITLEMENTS", relativeDestination);
  37.  
  38. // Add push notifications as a capability on the target
  39. proj.AddBuildProperty(target, "SystemCapabilities", "{com.apple.Push = {enabled = 1;};}");
  40. }
  41.  
  42. // Save the changed configs to the file
  43. File.WriteAllText(projPath, proj.WriteToString());
  44. }
  45. }

After that you just define the entitlementsFile variable for the script in the inspector window and you should now have the push notification activated by default when you build for iOS.

 

 

 

[출처] https://answers.unity.com/questions/1224123/enable-push-notification-in-xcode-project-by-defau.html

 

Enable Push Notification in XCode project by default? - Unity Answers

 

answers.unity.com

 

반응형
Posted by blueasa
, |