|
|
@@ -0,0 +1,512 @@
|
|
|
+using System.Collections;
|
|
|
+using System.Collections.Generic;
|
|
|
+using UnityEngine;
|
|
|
+using UnityEngine.AI;
|
|
|
+/* 动物组件-野鸡 */
|
|
|
+public class Yeji : TargetAnimal
|
|
|
+{
|
|
|
+ //动画播放器
|
|
|
+ Animator animator;
|
|
|
+ //寻路代理
|
|
|
+ NavMeshAgent agent;
|
|
|
+ //血量
|
|
|
+ [System.NonSerialized] public int hp = 3;
|
|
|
+ [System.NonSerialized] public TreeAreaRecorder treeAreaRecorder;
|
|
|
+ [System.NonSerialized] public float flyPlaneHeight = 5;
|
|
|
+ float currentHeight = 0;
|
|
|
+ float toFlyHeight = float.NaN;
|
|
|
+ public void SetFlyHeight(float value) {
|
|
|
+ if (toFlyHeight.Equals(float.NaN)) toFlyHeight = value;
|
|
|
+ currentHeight = value;
|
|
|
+ float agentBaseOffset = value - flyPlaneHeight;
|
|
|
+ this.agent.baseOffset = agentBaseOffset / transform.localScale.y;//因为agent的baseoffset会受节点的scale影响
|
|
|
+ state.flying = currentHeight > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ void Awake()
|
|
|
+ {
|
|
|
+ yejiSet.Add(this);
|
|
|
+ state = new State();
|
|
|
+ state.animal = this;
|
|
|
+ animator = GetComponent<Animator>();
|
|
|
+ agent = GetComponent<NavMeshAgent>();
|
|
|
+ this.agent.avoidancePriority = avoidancePriority;
|
|
|
+ this.onlineHandler.InitOnAwake(this);
|
|
|
+ }
|
|
|
+ static int _avoidancePriority = 0;
|
|
|
+ static int avoidancePriority {
|
|
|
+ get {
|
|
|
+ if (_avoidancePriority < 50) {
|
|
|
+ _avoidancePriority++;
|
|
|
+ } else {
|
|
|
+ _avoidancePriority = 1;
|
|
|
+ }
|
|
|
+ return _avoidancePriority;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void OnDestroy() {
|
|
|
+ yejiSet.Remove(this);
|
|
|
+ tryReleaseOccupyTree();
|
|
|
+ ReleasePreHeight(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ void Update()
|
|
|
+ {
|
|
|
+ this.onlineHandler.Update();
|
|
|
+ if (this.onlineHandler.isMirror) return;
|
|
|
+ //寻路过程监测
|
|
|
+ if (HasCloseToDestination()) {
|
|
|
+ OnReachDestination();
|
|
|
+ } else {
|
|
|
+ OnMovingToDestination();
|
|
|
+ }
|
|
|
+ UpdateAutoStrategy();
|
|
|
+ }
|
|
|
+
|
|
|
+ #region 被击触发
|
|
|
+ public override void OnHit(Arrow arrow, Vector3 hitPoint, string partName)
|
|
|
+ {
|
|
|
+ arrow.Head().position = hitPoint + arrow.transform.forward * 0.1f;
|
|
|
+ arrow.Hit();
|
|
|
+ if (onlineHandler.isMirror) {
|
|
|
+ onlineHandler.onHitData = onlineHandler.uid.ToString() + "," + partName;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ OnHitLogic(arrow, partName);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void OnHitLogic(Arrow arrow, string partName) {
|
|
|
+ int hurtValue = 0;
|
|
|
+ if (partName == "Wing") {
|
|
|
+ hurtValue = 1;
|
|
|
+ }
|
|
|
+ else if (partName == "Body") hurtValue = 2;
|
|
|
+ else if (partName == "Head") hurtValue = 3;
|
|
|
+ hp -= hurtValue;
|
|
|
+ GameEventCenter.ins.onTargetAnimalHurt?.Invoke(this, hurtValue);
|
|
|
+ if (hp <= 0) {
|
|
|
+ Die(arrow);
|
|
|
+ } else {
|
|
|
+ Hurt();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void Die(Arrow arrow) {
|
|
|
+ if (state.dead) return;
|
|
|
+ if (arrow != null) {
|
|
|
+ arrow.onDoNextShoot += delegate() {
|
|
|
+ Destroy(this.gameObject);
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ //需要借住关卡的GameMode来清除
|
|
|
+ onlineHandler.onDoNextShootWillDestroy = true;
|
|
|
+ }
|
|
|
+ this.animator.speed = 1;
|
|
|
+ state.dead = true;
|
|
|
+ this.agent.enabled = false;
|
|
|
+ ReleasePreHeight(this);
|
|
|
+ onDie?.Invoke(this);
|
|
|
+ AudioMgr.ins.PlayAnimalEffect("bird_injured", AudioMgr.GetAudioSource(this.gameObject));
|
|
|
+ this.onlineHandler.injuredID++;
|
|
|
+ if (currentHeight < 1.5f) {
|
|
|
+ if (arrow != null) arrow.arrowCameraComp.arrowCameraTemplate.SendMsg(0, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void Hurt() {
|
|
|
+ CancelStand();
|
|
|
+ CancelFlyStay();
|
|
|
+ AudioMgr.ins.PlayAnimalEffect("bird_injured", AudioMgr.GetAudioSource(this.gameObject));
|
|
|
+ this.onlineHandler.injuredID++;
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 寻路导航
|
|
|
+ bool _moving;
|
|
|
+ bool moving {
|
|
|
+ get { return _moving; }
|
|
|
+ set {
|
|
|
+ movingTime = 0;
|
|
|
+ _moving = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ float movingTime;
|
|
|
+ //启动寻路
|
|
|
+ void SetDestination(Vector3 pos) {
|
|
|
+ moving = true;
|
|
|
+ this.agent.destination = pos;
|
|
|
+ }
|
|
|
+ //寻路过程
|
|
|
+ void OnMovingToDestination() {
|
|
|
+ if (!moving) return;
|
|
|
+ movingTime += Time.deltaTime;
|
|
|
+ }
|
|
|
+ //寻路结束
|
|
|
+ void OnReachDestination() {
|
|
|
+ if (!moving) return;
|
|
|
+ moving = false;
|
|
|
+ }
|
|
|
+ //是否已经接近目的地(寻路完成判断)
|
|
|
+ bool HasCloseToDestination() {
|
|
|
+ if (!moving) return true;
|
|
|
+ return movingTime > 0.1 && this.agent.velocity.magnitude < 0.05f;
|
|
|
+ }
|
|
|
+ //停止寻路
|
|
|
+ void StopNavigation() {
|
|
|
+ if (!moving) return;
|
|
|
+ this.agent.destination = this.agent.nextPosition;
|
|
|
+ this.agent.velocity = Vector3.zero;
|
|
|
+ this.transform.position = this.agent.destination;
|
|
|
+ OnReachDestination();
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 自动逻辑
|
|
|
+ //自动策略的更新逻辑
|
|
|
+ void UpdateAutoStrategy() {
|
|
|
+ if (state.dead) return;
|
|
|
+ UpdateFlyUpDown();
|
|
|
+ UpdateBehavior();
|
|
|
+ }
|
|
|
+
|
|
|
+ float canStandTime = 3f;
|
|
|
+ float canFlyStayTime = 3f;
|
|
|
+ //能够在前几棵树徘徊
|
|
|
+ [System.NonSerialized] public int canFlyTreeCount = 3;
|
|
|
+ const float downSpeed = 2.0f;
|
|
|
+ //更新逻辑-起飞降落
|
|
|
+ void UpdateFlyUpDown() {
|
|
|
+ if (state.up && state.landing) { //起飞阶段
|
|
|
+ AnimatorStateInfo animatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
|
|
|
+ bool isTakeOff = animatorStateInfo.IsName("FlyFromGround");
|
|
|
+ if (isTakeOff) {
|
|
|
+ if (animatorStateInfo.normalizedTime >= 1.0) {
|
|
|
+ state.landing = false;
|
|
|
+ state.flying = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (state.up && state.flying) { //上升阶段
|
|
|
+ float surplusHeight = toFlyHeight - currentHeight;
|
|
|
+ float smoothValue = surplusHeight / toFlyHeight;
|
|
|
+ float nextFlyHeight = currentHeight + Time.deltaTime * (1f + 2.5f * smoothValue);
|
|
|
+ this.animator.speed = 1f + 2f * smoothValue;
|
|
|
+ if (nextFlyHeight >= toFlyHeight) { //上升完成
|
|
|
+ nextFlyHeight = toFlyHeight;
|
|
|
+ this.animator.speed = 1;
|
|
|
+ state.up = false;
|
|
|
+ }
|
|
|
+ SetFlyHeight(nextFlyHeight);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (state.down && state.flying) { //下降阶段
|
|
|
+ float nextH = currentHeight - Time.deltaTime * downSpeed;
|
|
|
+ if (nextH <= 0) { //下降完成
|
|
|
+ nextH = 0;
|
|
|
+ state.landing = true;
|
|
|
+ state.flying = false;
|
|
|
+ StopNavigation();
|
|
|
+ }
|
|
|
+ SetFlyHeight(nextH);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (state.down && state.landing) { //着落阶段
|
|
|
+ AnimatorStateInfo animatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
|
|
|
+ bool isLand = animatorStateInfo.IsName("LandOnGround");
|
|
|
+ if (isLand) {
|
|
|
+ if (animatorStateInfo.normalizedTime >= 1.0) {
|
|
|
+ state.down = false;
|
|
|
+ //进入站立状态
|
|
|
+ state.standing = true;
|
|
|
+ canStandTime = 8f + Random.value * 2f;
|
|
|
+ animator.CrossFade("IdleOnGround2", 0.2f);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ TreeAreaRecorder.AreaInfo targetAreaInfo;
|
|
|
+ bool needCheckFlyDown = false;
|
|
|
+ bool willStayOnTree = false;
|
|
|
+ void UpdateBehavior() {
|
|
|
+ if (state.flyStaying) {
|
|
|
+ canFlyStayTime -= Time.deltaTime;
|
|
|
+ if (canFlyStayTime <= 0) {
|
|
|
+ state.flyStaying = false;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state.standing) {
|
|
|
+ canStandTime -= Time.deltaTime;
|
|
|
+ if (canStandTime <= 0) {
|
|
|
+ CancelStand();
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state.landing) return;
|
|
|
+
|
|
|
+ if (state.flying && !state.down && !state.up) {
|
|
|
+ if (needCheckFlyDown) {
|
|
|
+ float downNeedTime = currentHeight / downSpeed;
|
|
|
+ float keyDistance = this.agent.speed * downNeedTime; //触发下降的水平距离阈值
|
|
|
+ Vector3 myP = this.transform.position;
|
|
|
+ Vector3 desP = this.agent.destination;
|
|
|
+ desP.y = myP.y;
|
|
|
+ float distance = Vector3.Distance(myP, desP);
|
|
|
+ if (distance < keyDistance) {
|
|
|
+ needCheckFlyDown = false;
|
|
|
+ if (Random.value < 0.5 && tryOccupyTree()) {
|
|
|
+ state.down = true;
|
|
|
+ } else {
|
|
|
+ willStayOnTree = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (moving) return;
|
|
|
+
|
|
|
+ if (willStayOnTree) {
|
|
|
+ willStayOnTree = false;
|
|
|
+ state.flyStaying = true;
|
|
|
+ canFlyStayTime = 9f + Random.value * 1f;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ AnimatorStateInfo animatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
|
|
|
+ if (animatorStateInfo.IsName("Yeji Fly Form Tree") || animatorStateInfo.IsName("Yeji Idle On Tree 01") || animatorStateInfo.IsName("Yeji Land On Tree")) {
|
|
|
+ //该动作期间还不能适合执行移动,所以先返回
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //飞向别的树
|
|
|
+ #region
|
|
|
+ Vector3 myPos = this.transform.position;
|
|
|
+ TreeAreaRecorder.AreaInfo[] areaInfos = treeAreaRecorder.copyAreaInfos(canFlyTreeCount);
|
|
|
+ for (int i = 0; i < canFlyTreeCount; i++) {
|
|
|
+ areaInfos[i].teamCompareValue = areaInfos[i].distanceInHorizontal(myPos);
|
|
|
+ }
|
|
|
+ System.Array.Sort(areaInfos, new ComparerAreaInfosByDistance());
|
|
|
+ TreeAreaRecorder.AreaInfo areaInfo = areaInfos[Random.Range(1, canFlyTreeCount)];
|
|
|
+ Vector3 newPos = YejiHuntGameMode.CalculateNewPosByTreePos(animalsBaseT, flyPlaneHeight, areaInfo);
|
|
|
+ SetDestination(newPos);
|
|
|
+ targetAreaInfo = areaInfo;
|
|
|
+ needCheckFlyDown = true;
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+
|
|
|
+ class ComparerAreaInfosByDistance : IComparer {
|
|
|
+ public int Compare(object x, object y) {
|
|
|
+ TreeAreaRecorder.AreaInfo a = (TreeAreaRecorder.AreaInfo)x;
|
|
|
+ TreeAreaRecorder.AreaInfo b = (TreeAreaRecorder.AreaInfo)y;
|
|
|
+ if (a.teamCompareValue - b.teamCompareValue > 0) return 1;
|
|
|
+ if (a.teamCompareValue - b.teamCompareValue < 0) return -1;
|
|
|
+ else return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ void CancelStand() {
|
|
|
+ if (!state.standing) return;
|
|
|
+ state.standing = false;
|
|
|
+ state.up = true;
|
|
|
+ animator.CrossFade("FlyFromGround", 0.1f);
|
|
|
+ tryReleaseOccupyTree();
|
|
|
+ }
|
|
|
+
|
|
|
+ void CancelFlyStay() {
|
|
|
+ if (!state.flyStaying) return;
|
|
|
+ canFlyStayTime = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool tryOccupyTree() {
|
|
|
+ if (targetAreaInfo == null) return false;
|
|
|
+ if (targetAreaInfo.occupy != null) return false;
|
|
|
+ else {
|
|
|
+ targetAreaInfo.occupy = this;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void tryReleaseOccupyTree() {
|
|
|
+ if (targetAreaInfo != null && targetAreaInfo.occupy != null && targetAreaInfo.occupy.Equals(this)) {
|
|
|
+ targetAreaInfo.occupy = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static float[] preFlyHeights;
|
|
|
+ static object[] preFlyHeightCools;
|
|
|
+ public static void InitPreHeights() {
|
|
|
+ preFlyHeights = new float[]{1.3f, 2.3f};
|
|
|
+ preFlyHeightCools = new object[]{null, null};
|
|
|
+ }
|
|
|
+ public static float RandomOnePreHeight(Yeji yeji) {
|
|
|
+ for (int i = 0; i < preFlyHeightCools.Length; i++) {
|
|
|
+ if (preFlyHeightCools[i] == null) {
|
|
|
+ preFlyHeightCools[i] = yeji;
|
|
|
+ return preFlyHeights[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 2.5f;
|
|
|
+ }
|
|
|
+ public static void ReleasePreHeight(Yeji yeji) {
|
|
|
+ for (int i = 0; i < preFlyHeightCools.Length; i++) {
|
|
|
+ if (yeji.Equals(preFlyHeightCools[i])) {
|
|
|
+ preFlyHeightCools[i] = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ //状态
|
|
|
+ [System.Serializable]
|
|
|
+ public class State {
|
|
|
+ public bool standing = false;
|
|
|
+ [SerializeField] private bool _flyStaying = false;
|
|
|
+ public bool flyStaying {
|
|
|
+ get { return _flyStaying; }
|
|
|
+ set {
|
|
|
+ _flyStaying = value;
|
|
|
+ animal.animator.SetBool("flyStaying", value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ [SerializeField] private bool _dead;
|
|
|
+ public bool dead {
|
|
|
+ get { return _dead; }
|
|
|
+ set {
|
|
|
+ _dead = value;
|
|
|
+ animal.animator.SetBool("dead", value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ [SerializeField] private bool _down;
|
|
|
+ public bool down {
|
|
|
+ get { return _down; }
|
|
|
+ set {
|
|
|
+ _down = value;
|
|
|
+ animal.animator.SetBool("down", value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ [SerializeField] private bool _landing;
|
|
|
+ public bool landing {
|
|
|
+ get { return _landing; }
|
|
|
+ set {
|
|
|
+ _landing = value;
|
|
|
+ animal.animator.SetBool("landing", value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ [SerializeField] private bool _up;
|
|
|
+ public bool up {
|
|
|
+ get { return _up; }
|
|
|
+ set {
|
|
|
+ _up = value;
|
|
|
+ animal.animator.SetBool("up", value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ [SerializeField] private bool _flying;
|
|
|
+ public bool flying {
|
|
|
+ get { return _flying; }
|
|
|
+ set {
|
|
|
+ _flying = value;
|
|
|
+ animal.animator.SetBool("flying", value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public Yeji animal;
|
|
|
+ }
|
|
|
+ [SerializeField] public State state;
|
|
|
+
|
|
|
+ //委托
|
|
|
+ public System.Action<Yeji> onDie;
|
|
|
+
|
|
|
+ #region 联机附加部分
|
|
|
+ public static HashSet<Yeji> yejiSet = new HashSet<Yeji>();
|
|
|
+ public OnlineHandler onlineHandler = new OnlineHandler();
|
|
|
+ public class OnlineHandler {
|
|
|
+ Yeji animal;
|
|
|
+ public int uid;
|
|
|
+ public bool isMirror;
|
|
|
+ public int mirrorState = 0;
|
|
|
+ public float animatroSpeed = 1;
|
|
|
+ public YejiSyncData outputSyncData;
|
|
|
+ public void InitOnAwake(Yeji animal) {
|
|
|
+ this.animal = animal;
|
|
|
+ if (isMirror) {
|
|
|
+ GameObject.Destroy(this.animal.agent);
|
|
|
+ this.animal.animator.SetLayerWeight(1, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public void Update() {
|
|
|
+ if (isMirror) {
|
|
|
+ if (inputSyncData == null) return;
|
|
|
+ if (!hasUpdateBySyncData) {
|
|
|
+ this.animal.transform.position = syncPosition;
|
|
|
+ this.animal.transform.rotation = syncRotation;
|
|
|
+ hasUpdateBySyncData = true;
|
|
|
+ } else {
|
|
|
+ this.animal.transform.position = Vector3.Lerp(this.animal.transform.position, syncPosition, Time.deltaTime * 15);
|
|
|
+ this.animal.transform.rotation = Quaternion.Lerp(this.animal.transform.rotation, syncRotation, Time.deltaTime * 15);
|
|
|
+ }
|
|
|
+ this.animal.animator.SetInteger("mirrorState", mirrorState);
|
|
|
+ this.animal.animator.speed = animatroSpeed;
|
|
|
+ if (inputSyncData.ii != injuredID) {
|
|
|
+ injuredID = inputSyncData.ii;
|
|
|
+ AudioMgr.ins.PlayAnimalEffect("bird_injured", AudioMgr.GetAudioSource(this.animal.gameObject));
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (GlobalData.pkMatchType == PKMatchType.OnlinePK) {
|
|
|
+ if (outputSyncData == null) outputSyncData = new YejiSyncData();
|
|
|
+ int curStateHash = this.animal.animator.GetCurrentAnimatorStateInfo(0).fullPathHash;
|
|
|
+ mirrorState = System.Array.IndexOf(stateHashList, curStateHash);
|
|
|
+ animatroSpeed = this.animal.animator.speed;
|
|
|
+ outputSyncData.SetData(this.animal);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private YejiSyncData _inputSyncData;
|
|
|
+ public YejiSyncData inputSyncData {
|
|
|
+ get {
|
|
|
+ return _inputSyncData;
|
|
|
+ }
|
|
|
+ set {
|
|
|
+ _inputSyncData = value;
|
|
|
+ uid = value.id;
|
|
|
+ syncRotation.x = value.rx;
|
|
|
+ syncRotation.y = value.ry;
|
|
|
+ syncRotation.z = value.rz;
|
|
|
+ syncRotation.w = value.rw;
|
|
|
+ syncPosition.x = value.px;
|
|
|
+ syncPosition.y = value.py;
|
|
|
+ syncPosition.z = value.pz;
|
|
|
+ mirrorState = value.ms;
|
|
|
+ animatroSpeed = value.asp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private Quaternion syncRotation;
|
|
|
+ private Vector3 syncPosition;
|
|
|
+ private bool hasUpdateBySyncData = false;
|
|
|
+ public bool isInvalid = false; //外部运算用的
|
|
|
+ public string onHitData = null;
|
|
|
+ public bool onDoNextShootWillDestroy = false;
|
|
|
+ public int injuredID = 0;
|
|
|
+ private int[] stateHashList = {
|
|
|
+ Animator.StringToHash("Base Layer.Fly"),
|
|
|
+ Animator.StringToHash("Base Layer.FlyUp"),
|
|
|
+ Animator.StringToHash("Base Layer.FlyFromGround"),
|
|
|
+ Animator.StringToHash("Base Layer.FlyDown"),
|
|
|
+ Animator.StringToHash("Base Layer.LandOnGround"),
|
|
|
+ Animator.StringToHash("Base Layer.IdleOnGround2"),
|
|
|
+ Animator.StringToHash("Base Layer.Yeji Idle On Tree 01"),
|
|
|
+ Animator.StringToHash("Base Layer.Yeji Land On Tree"),
|
|
|
+ Animator.StringToHash("Base Layer.Yeji Fly Form Tree"),
|
|
|
+ Animator.StringToHash("Base Layer.DeadOnSky"),
|
|
|
+ Animator.StringToHash("Base Layer.DeadOnGround")
|
|
|
+ };
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ public override int GetOnlineID() {
|
|
|
+ return onlineHandler.uid;
|
|
|
+ }
|
|
|
+}
|