#c# #unity3d
#c# #unity3d
Вопрос:
Это мой код для контроллера animator в unity, который работает нормально, но показал, что он просто повторяется снова и снова для изменения некоторых переменных. Мой вопрос в том, есть ли способ создать словарь на C #, чтобы сделать его менее повторяющимся. Я полагаю, что должен быть способ, но поскольку я новичок в c #, я был бы благодарен за помощь
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class anim : MonoBehaviour
{
[SerializeField] private Animator animator = null;
private static readonly int hashHappy = Animator.StringToHash("happy");
private static readonly int hashSad = Animator.StringToHash("sad");
void Update()
{
if(Input.GetKey(KeyCode.H))
{
animator.SetBool(hashHappy, true);
animator.SetBool(hashSad, false);
} else if (Input.GetKeyUp(KeyCode.H))
{
Invoke("finishHappy", 5f);
}
if(Input.GetKey(KeyCode.S)){
animator.SetBool(hashHappy, false);
animator.SetBool(hashSad, true);
} else if (Input.GetKeyUp(KeyCode.S))
{
Invoke("finishSad", 5f);
}
}
public void finishHappy()=>animator.SetBool(hashHappy, false);
public void finishSad()=>animator.SetBool(hashSad, false);
}
Ответ №1:
Честно говоря, я понятия не имею, имеет ли смысл то, что вы делаете, поскольку у меня ограниченные знания Unity.
Однако структура данных, которую я бы использовал, была бы List<T>
. Это позволит вам перебирать хэши и переключать анимацию.
Учитывая
public static class SomeClass
{
private static readonly int hashHappy = Animator.StringToHash("happy");
private static readonly int hashClap = Animator.StringToHash("clap");
private static readonly int hashSad = Animator.StringToHash("sad");
private static readonly int hashAngry = Animator.StringToHash("angry");
private static readonly int hashDance = Animator.StringToHash("dance");
private static readonly int hashDie = Animator.StringToHash("die");
privatestatic List<int> _hashes;
static SomeClass()
{
_hashes = new List<int>() {hashHappy, hashClap, hashSad, hashAngry, hashDance, hashDie};
}
public static void Set(Animator animator, int hash)
{
foreach (var item in _hashes)
animator.SetBool(hash, item == hash);
}
}
использование
if(Input.GetKey(KeyCode.H))
SomeClass.Set(animator, hashHappy);
if(Input.GetKey(KeyCode.C))
SomeClass.Set(animator, hashClap);
Ответ №2:
Я, вероятно, был бы склонен использовать словарь, как вы сначала подумали. А затем соедините это с некоторыми перечислениями для ваших выражений. Конечный результат будет выглядеть примерно так:
public enum ExpressionType
{
None,
Happy,
Sad,
Angry,
// etc. etc.
}
public class anim : MonoBehaviour
{
[SerializeField] private Animator animator = null;
private static Dictionary<ExpressionType, int> expressions = new Dictionary<ExpressionType, int> ( )
{
[ ExpressionType.Happy ] = Animator.StringToHash ( "happy" ),
[ ExpressionType.Sad ] = Animator.StringToHash ( "sad" ),
[ ExpressionType.Angry ] = Animator.StringToHash ( "angry" ),
};
private static anim _instance;
private void Awake ( )
{
_instance = this;
}
public static bool Set ( ExpressionType e = ExpressionType.None )
{
if ( _instance ) return false;
foreach ( var kv in expressions )
_instance.animator.SetBool ( kv.Value, kv.Key == e );
return true;
}
void Update ( )
{
if ( Input.GetKeyDown ( KeyCode.H ) )
Set ( ExpressionType.Happy );
else if ( Input.GetKeyUp ( KeyCode.H ) )
Invoke ( "Set", 5f );
if ( Input.GetKey ( KeyCode.S ) )
Set ( ExpressionType.Sad );
else if ( Input.GetKeyUp ( KeyCode.S ) )
Invoke ( "Set", 5f );
}
}
Передача без аргумента статическому Set
методу приведет к тому, что все значения bool будут установлены в false , и именно поэтому Invoke("Set", 5f)
можно использовать вызов, вместо того, чтобы пытаться точно указать, какое логическое значение animator установить в false .
Вы могли бы добавить отдельный Reset
метод, если хотите сэкономить пару ненужных вызовов аниматора, но это ничего не сломает, если оставить все как есть.
Обратите внимание, что это действительно полезно только в том случае, если вы используете значение bool animator . Установка триггера или передача значений потребуют Set
выполнения некоторых дополнительных проверок типов данных. И последнее замечание, чтобы сказать, что я написал, но не тестировал код. Похоже, это должно сработать.
Комментарии:
1. спасибо за объяснение и код, у меня все работает нормально