Unity 3 D-カメラスムーズフォロー(方法一)


using UnityEngine;
using System.Collections;

public class SmoothFollowerObj : MonoBehaviour {

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

次のスクリプトはカメラに割り当てられ、追従された物体はcharacterに割り当てられる.
using UnityEngine;
using System.Collections;

public class NoGravityCamera : MonoBehaviour {

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

    // Use this for initialization
    void Start()
    {
        //positionVector = new Vector3(0, 2, 4);
        //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;
    }

    // Update is called once per frame
    void LateUpdate()
    {
        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;
    }
}

http://game.ceeger.com/forum/read.php?tid=1171