实现宠物平滑跟随

using UnityEngine;
using System.Collections;

/// <summary>
/// 宠物逻辑控制
/// </summary>
public class PetController:MonoBehaviour
{
    public Transform target;
    public float distance =1.7f;
    public float height = 1.0f;
    public float heightDamping = 0.5f;
    public float rotationDamping = 0.3f;
    private float _RefRotation = 0f;
    private float _RefHigh = 0f;

    private  GameObject mRole;//当前角色
    private NavMeshAgent agent;
    private GameObject mPetAni;
    private Animation Ani;

    public GameObject character;
    public Vector3 positionVector;
    public Vector3 lookVector;
    private SmoothFollowerObj posFollow;
    private SmoothFollowerObj lookFollow;
    private Vector3 lastVelocityDir;
    private Vector3 lastPos;


    void Start()
    {
        int id = PlayerPrefs.GetInt("RoleID");
        Debug.Log(id);
        string UserName = PlayerDataManager.Instance.Attrib.Name;
        Debug.Log(UserName);
        agent = GetComponent<NavMeshAgent>();
        agent.enabled = true;
        if (id == 1004)
        {
            character = GameObject.Find("Amazon(Clone)");
            mRole = GameObject.Find("Amazon(Clone)"); //拿到当前角色的位置!
            target = mRole.transform;
        }
        if (id == 1003)
        {
            character = GameObject.Find("Warrior(Clone)");
            mRole = GameObject.Find("Warrior(Clone)");
            target = mRole.transform;

        }
        if (id == 1005)
        {
            character = GameObject.Find("Magician(Clone)");
            mRole = GameObject.Find("Magician(Clone)");
            target = mRole.transform;

        }
        if (id == 1006)
        {
            character = GameObject.Find("Wukong(Clone)");
            mRole = GameObject.Find("Wukong(Clone)");
            target = mRole.transform;
        }
        mPetAni = this.transform.GetChild(0).gameObject;
        Ani = mPetAni.GetComponent<Animation>();       
        Debug.Log(mPetAni.name);
        Debug.Log(mRole.transform.position);
        transform.LookAt(mRole.transform.position);
        transform.position = mRole.transform.position + new Vector3(0, 0, -1);

        positionVector = new Vector3(0, 0.5f, 1.7f);
        lookVector = new Vector3(0, 0, 1.5f);
        posFollow = new SmoothFollowerObj(0.5f, 0.5f);
        lookFollow = new SmoothFollowerObj(0.1f, 0.0f);
        posFollow.Update(transform.position, 0, true);
        lookFollow.Update(character.transform.position, 0, true);
        lastVelocityDir = character.transform.forward;
        lastPos = character.transform.position;
    }
    void FixedUpdate()
    {
        if (mRole != null)
        {
            float s =  Vector3.Distance(transform.position, mRole.transform.position);
            if (Vector3.Distance(transform.position, mRole.transform.position) > 2.0f)
            {
                if (Application.loadedLevelName == "NewMain01")
                {
                 //   agent.destination = mRole.transform.position + (mRole.transform.position - transform.position);

                    Debug.Log(mRole.transform.position);

                    float a = Random.Range(1, -1);

             //       transform.RotateAround(mRole.transform.position, Vector3.up, Time.deltaTime*180);
                    PetMoveFllow();
                }
                else
                {
                    PetMoveFllow();
                    // this.transform.position = mRole.transform.position + new Vector3(0, 0, -1);
                }
                if (GameObject.Find("TJ(Clone)") != null)
                {
                    PlayAni("tj_pao_01");
                }else
                if (GameObject.Find("HYS(Clone)") != null)
                {
                    PlayAni("hys_pao_01");
                }else
                if (GameObject.Find("XSJ(Clone)") != null)
                {
                    PlayAni("xsj_pao_01");
                }
                //Ani.Play("tj_pao_01");
            }
            else
            {
                if (GameObject.Find("TJ(Clone)") != null)
                {
                    PlayAni("tj_daiji_01");
                }else
                if (GameObject.Find("HYS(Clone)") != null)
                {
                    PlayAni("hys_daiji_01");
                }else
                if (GameObject.Find("XSJ(Clone)") != null)
                {
                    PlayAni("xsj_daiji_01");
                }
            }
        }
        transform.LookAt(mRole.transform.position, Vector3.up);
    }

    private void PetMoveFllow()
    {
        //if (!target)
        //    return;
        //float wantedRotationAngle = target.eulerAngles.y;
        //float wantedHeight = target.position.y + height;
        //float currentRotationAngle = transform.eulerAngles.y;
        //float currentHeight = transform.position.y;
        //currentRotationAngle = Mathf.SmoothDampAngle(currentRotationAngle, wantedRotationAngle, ref _RefRotation, rotationDamping);
        //currentHeight = Mathf.SmoothDamp(currentHeight, wantedHeight, ref _RefHigh, heightDamping);
        //Quaternion currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
        //transform.position = target.position;
        //transform.position -= currentRotation * Vector3.forward * distance;
        //transform.position =  new Vector3(transform.position.x, currentHeight, transform.position.z);

        //Debug.Log(" 场景名称:" + Application.loadedLevelName);


        lastVelocityDir += (character.transform.position - lastPos) * 8;
        lastPos = character.transform.position;
        lastVelocityDir += character.transform.forward * Time.deltaTime;
        lastVelocityDir = lastVelocityDir.normalized;
        Vector3 horizontal = transform.position - character.transform.position;
        Vector3 horizontal2 = horizontal;
        Vector3 vertical = character.transform.up;
        Vector3.OrthoNormalize(ref vertical, ref horizontal2);
        if (horizontal.sqrMagnitude > horizontal2.sqrMagnitude) horizontal = horizontal2;
        transform.position = posFollow.Update(
            character.transform.position + horizontal * Mathf.Abs(positionVector.z) + vertical * positionVector.y,
            Time.deltaTime
        );

        horizontal = lastVelocityDir;
        Vector3 look = lookFollow.Update(character.transform.position + horizontal * lookVector.z - vertical * lookVector.y, Time.deltaTime);
        transform.rotation = Quaternion.FromToRotation(transform.forward, look - transform.position) * transform.rotation;

    }
    void PlayAni(string aniName)
    {
        if (aniName != null)
        {
            Ani.CrossFade(aniName,0.2f);
        }
        else
        {
            Debug.Log("不存在当前的宠物名称!");
        }
    }
}
public 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;
    }

    // Update should be called once per frame
    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; }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值