unity 实现简单的宠物跟随(平滑处理)

2018-9-15 雨辰 遇到的一些问题

1: 玩家移动类

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);
	
	}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

2:宠物跟随移动类

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;

	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 LateUpdate() {
        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;
        }

        // 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; }
    }
}

标签: Unity3D

发表评论:

雨辰 joyimp|@2011-2018 京ICP备16030765号