Unity实现宠物跟随移动
发表于2018-08-02
多数RPG游戏中都有宠物,如果确保主角移动过程中宠物会跟随着一起移动,下面就给大家介绍下实现宠物跟随移动的方法。
简单的跟随移动
玩家移动控制脚本:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMove : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { float h = Input.GetAxis ("Horizontal"); float v = Input.GetAxis ("Vertical"); if(h!=0 || v!=0){ transform.LookAt (transform.position+new Vector3(h,0,v)); transform.Translate (transform.forward*Time.deltaTime*5f,Space.World); } } }
跟对对象移动控制脚本:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PetMove : MonoBehaviour { public Transform player;//主角 public float speed=1f;//移动的阻尼,值越小,移动越平缓 // Use this for initialization void Start () { } // Update is called once per frame void Update () {//如果主角和宠物直接的距离大于5,控制宠物跟随主角移动 if(Vector3.Distance(player.position,transform.position)>5f){ PetSmothFlow (); //to do。。播放移动动画 } //to do。。播放站立动画 //控制宠物的朝向 transform.LookAt (player.position); } //控制宠物的位置平滑移动 void PetSmothFlow(){ transform.position=Vector3.Lerp (transform.position,player.position,Time.deltaTime*speed); } }
宠物跟随移动
玩家移动控制脚本:
using UnityEngine; using System.Collections; public class PlayerMove : MonoBehaviour { public float speed = 8f; Animator anim; // Use this for initialization void Start () { anim = this.GetComponent<Animator>(); } // Update is called once per frame void Update () { float h = Input.GetAxis("Horizontal"); float v=Input.GetAxis("Vertical"); if (Mathf.Abs(h) > 0 || Mathf.Abs(v) > 0) { transform.LookAt(transform.position + new Vector3(h, 0, v)); transform.Translate(transform.forward * Time.deltaTime * speed, Space.World); anim.SetBool("Run", true); } else anim.SetBool("Run",false); } }
跟对对象移动控制脚本:
using UnityEngine; using System.Collections; public class PetFlow : MonoBehaviour { public Transform player; public float maxDis = 5; Animator anim; private SmoothFollowerObj posFollow;//控制位置平滑移动 private SmoothFollowerObj lookFollow;//控制朝向平滑转换 public Vector3 positionVector;//角色位置移动的时候,方向向量 public Vector3 lookVector;//角色朝向变化的时候,朝向向量 private Vector3 lastVelocityDir;//上一次移动的方向 private Vector3 lastPos;//之前移动的目标点位置 // Use this for initialization void Start () { anim = this.GetComponent<Animator>();//获取动画控制器 posFollow = new SmoothFollowerObj(0.5f, 0.5f); lookFollow = new SmoothFollowerObj(0.1f, 0.0f); posFollow.Update(transform.position, 0, true);//初始化负值 lookFollow.Update(player.transform.position, 0, true); positionVector = new Vector3(0, 0.5f, 1.7f); lookVector = new Vector3(0, 0, 1.5f); lastVelocityDir = player.transform.forward; lastPos = player.transform.position; } // Update is called once per frame void Update () { float dis = Vector3.Distance(transform.position,player.position); if (dis > maxDis)//如果玩家和宠物之间的距离大于允许的最大距离,控制宠物向玩家移动 { PetMoveFlow();//宠物移动的逻辑 anim.SetBool("Run", true); } else { anim.SetBool("Run",false); } transform.LookAt(player.position,Vector3.up); } private void PetMoveFlow() { lastVelocityDir += (player.transform.position - lastPos) * 5; lastPos = player.transform.position; lastVelocityDir += player.transform.forward * Time.deltaTime; lastVelocityDir = lastVelocityDir.normalized; Vector3 horizontal = transform.position - player.transform.position; Vector3 horizontal2 = horizontal; Vector3 vertical = player.transform.up; Vector3.OrthoNormalize(ref vertical, ref horizontal2); if (horizontal.sqrMagnitude > horizontal2.sqrMagnitude) horizontal = horizontal2; transform.position = posFollow.Update( player.transform.position + horizontal * Mathf.Abs(positionVector.z) + vertical * positionVector.y, Time.deltaTime ); horizontal = lastVelocityDir; Vector3 look = lookFollow.Update(player.transform.position + horizontal * lookVector.z - vertical * lookVector.y, Time.deltaTime); transform.rotation = Quaternion.FromToRotation(transform.forward, look - transform.position) * transform.rotation; } class SmoothFollowerObj { private Vector3 targetPosition; private Vector3 position; private Vector3 velocity; private float smoothingTime; private float prediction; public SmoothFollowerObj(float smoothingTime) { targetPosition = Vector3.zero; position = Vector3.zero; velocity = Vector3.zero; this.smoothingTime = smoothingTime; prediction = 1; } public SmoothFollowerObj(float smoothingTime, float prediction) { targetPosition = Vector3.zero; position = Vector3.zero; velocity = Vector3.zero; this.smoothingTime = smoothingTime; this.prediction = prediction; } // 更新位置信息 public Vector3 Update(Vector3 targetPositionNew, float deltaTime) { Vector3 targetVelocity = (targetPositionNew - targetPosition) / deltaTime;//获取目标移动的方向向量 targetPosition = targetPositionNew; float d = Mathf.Min(1, deltaTime / smoothingTime); velocity = velocity * (1 - d) + (targetPosition + targetVelocity * prediction - position) * d; position += velocity * Time.deltaTime; return position; } //根据传递进来的数据,重置本地参数 public Vector3 Update(Vector3 targetPositionNew, float deltaTime, bool reset) { if (reset) { targetPosition = targetPositionNew; position = targetPositionNew; velocity = Vector3.zero; return position; } return Update(targetPositionNew, deltaTime); } public Vector3 GetPosition() { return position; } public Vector3 GetVelocity() { return velocity; } } }