Unityで2DRPGを作ってみる 4日目
忙しくて長らくUnityを触れていなかったのですが、前の記事から半年経ってるので何か書かねばと思い立ちました。
3日目まではUnity4.6で作っていたのですが、昨日Unityのサイトを見ていたら、Unity5.0.2ってのが出てたので早速ダウンロードして使ってみました。
4.6との違い
正直まだ良くわかっていませんw
ただ、1日目に作ったクラス
kotonaga.hatenablog.com
がエラー出まくりになりましたw
問題の確認
UnityEditorInternal関係のクラスが殆ど(全部?)obsoleteになっていました。
代わりにUnityEditor.Animationsを使えってことなので、それを使うことにしました。
プログラムの変更
何か色々苦労したのでもはや覚えていないのですが、UnityEditor.Animationsの中のクラスが、前のUnityEditorInternalのクラスと名前が同じでも使い方が違ったり、メソッドが異なる等で結構書き換えました。
こんな感じ
/* The MIT License (MIT) Copyright (c) 2015 Kotonaga Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #if UNITY_EDITOR using UnityEngine; using UnityEditor; using UnityEditor.Animations; [ExecuteInEditMode()] public class Character : MonoBehaviour { ////// ウディタ用キャラクタ画像素材 /// public Texture2D m_image; ////// 1セルの幅 /// public int m_cropWidth; ////// 1セルの高さ /// public int m_cropHeight; void Awake () { if(this.m_image==null) return; // スプライトレンダラの取得 SpriteRenderer spriteRenderer = gameObject.GetComponent(); // アニメータの取得 Animator animator = gameObject.GetComponent (); // ぼやけを除去 this.m_image.filterMode = FilterMode.Point; // 15フレームに一回アニメーションする float frameLength = 15f / 60f; // 画像は横にアニメーションする int frameCount = this.m_image.width / this.m_cropWidth; // 画像は縦に種類が並んでいる int stateCount = this.m_image.height / this.m_cropHeight; bool extendedCharaChipSet = false; // ただし、8方向のチップセットが存在するので、それに対処する if(frameCount==6 || frameCount==10){ frameCount >>= 1; stateCount <<= 1; extendedCharaChipSet = true; } // スプライト配列の作成 Sprite[,] sprites = new Sprite[stateCount, frameCount]; // Blend Tree 設定用のVector2配列の準備 Vector2[] positions = { new Vector2(0, 1), new Vector2(1, 0), new Vector2(-1, 0), new Vector2(0, -1), new Vector2(1, 1), new Vector2(-1, 1), new Vector2(1, -1), new Vector2(-1, -1), }; // アニメータコントローラの作成 AnimatorController animatorController = new AnimatorController (); // 名前はテクスチャ名にする animatorController.name = this.m_image.name; //向きと状態指定用のパラメータを追加 animatorController.AddParameter ("DirectionX", AnimatorControllerParameterType.Float); animatorController.AddParameter ("DirectionY", AnimatorControllerParameterType.Float); animatorController.AddParameter ("Walking", AnimatorControllerParameterType.Bool); // アニメータコントローラにベースレイヤを追加 animatorController.AddLayer ("Base"); // 歩き状態を追加する BlendTree walkBlendTree; AnimatorState walkState = animatorController.CreateBlendTreeInController("Walk", out walkBlendTree); walkBlendTree.name = "Blend Tree"; // 歩き状態は歩く方向によってアニメーションが変化する walkBlendTree.blendType = BlendTreeType.SimpleDirectional2D; walkBlendTree.blendParameter = "DirectionX"; walkBlendTree.blendParameterY = "DirectionY"; // 状態の数だけループ for (int y=0; y =(stateCount>>1)){ offsetX = frameCount; offsetY = -(stateCount>>1); } // スプライトの切り出しと普通のアニメーションの作成 for (int x=0; x 1枚目とアニメーションする for (int x=1; x>=0; x--) { int index = frameCount + 1 -x; keyFrames [index] = new ObjectReferenceKeyframe{time=index*frameLength, value=sprites[y,x]}; } // アニメーションクリップの作成 // 名前は状態のインデックスにする AnimationClip clip = new AnimationClip (); clip.name = y.ToString (); // はみ出た部分は消す clip.wrapMode = WrapMode.Clamp; // カーブの作成 EditorCurveBinding curveBinding = new EditorCurveBinding (); // ファイルは存在しない curveBinding.path = string.Empty; // スプライトをアニメーションするのでtypeにSpriteRenderer // propertyNameにはm_Spriteを指定 curveBinding.type = typeof(SpriteRenderer); curveBinding.propertyName = "m_Sprite"; // クリップとカーブにキーフレームをバインド AnimationUtility.SetObjectReferenceCurve (clip, curveBinding, keyFrames); // LoopTimeが直接設定出来ないので一旦シリアライズする SerializedObject serializedClip = new SerializedObject (clip); // アニメーションクリップ設定の取り出し AnimationClipSettings animationClipSettings = new AnimationClipSettings (serializedClip.FindProperty ("m_AnimationClipSettings")); // LoopTimeを有効にする animationClipSettings.LoopTime = true; // 設定を書き戻す serializedClip.ApplyModifiedProperties (); // 状態を歩き状態のブレンドツリーに追加 walkBlendTree.AddChild (clip, positions[y]); } // 止まり状態を追加する BlendTree waitBlendTree; AnimatorState waitState = animatorController.CreateBlendTreeInController("Wait", out waitBlendTree); waitBlendTree.name = "Blend Tree"; // 止まり状態はアニメーションしないが // 方向によってスプライトが変化する waitBlendTree.blendType = BlendTreeType.SimpleDirectional2D; waitBlendTree.blendParameter = "DirectionX"; waitBlendTree.blendParameterY = "DirectionY"; // 状態の数だけループ for (int i=0; i 歩きのトランジションを作成 AnimatorStateTransition waitToWalk = waitState.AddTransition(walkState); // Walkingフラグがtrueの時 waitToWalk.AddCondition(AnimatorConditionMode.If,0,"Walking"); // 歩き->止まりのトランジションを作成 AnimatorStateTransition walkToWait = walkState.AddTransition(waitState); // Walkingフラグがfalseの時 walkToWait.AddCondition(AnimatorConditionMode.IfNot,0,"Walking"); // アニメータコントローラに設定 animator.runtimeAnimatorController = (animatorController as RuntimeAnimatorController); // とりあえず0,0のスプライトをデフォルトにセット spriteRenderer.sprite = sprites[0,0]; } } /// /// AnimationClipSettingsの設定用クラス /// class AnimationClipSettings { SerializedProperty m_property; public AnimationClipSettings (SerializedProperty prop) { this.m_property = prop; } private SerializedProperty Get (string property) { return this.m_property.FindPropertyRelative (property); } public bool LoopTime { get { return this.Get ("m_LoopTime").boolValue; } set { this.Get ("m_LoopTime").boolValue = value; } } } #endif
まとめ
変更点はまだ良く分かっていません。
とりあえずこのクラスだけ直したら、他は前のままで動くようになりました。
フィールドマップを早く実装したい所ですが、まだ出来ていません…