2012年2月8日 星期三

【程式範例】角色控制

從官方的範例裡面抽出來的程式
還沒有改完成,但可以參考,程式複雜已失去重力,所以腳色不會掉落
直接拖曳到物件上就可以使用,但必須先設定角色碰撞
@script RequireComponent(Rigidbody)

public var movementDirection : Vector3 = Vector3(1,0,0);
public var movementTarget : Vector3;
public var facingDirection : Vector3;
public var walkingSpeed: float = 5.0;
public var walkingSnappyness: float = 50; //走路的節拍
public var turningSmoothing: float = 0.3; //平滑轉動
private var character: Transform;
public var cursorPlaneHeight: float = 0;
private var mainCamera: Camera;
private var mainCameraTransform: Transform;
private var playerMovementPlane: Plane;
private var screenMovementSpace: Quaternion;
private var screenMovementForward: Vector3;
private var screenMovementRight: Vector3;

    function Awake() {
        movementDirection = Vector2.zero;
        facingDirection = Vector2.zero;
        mainCamera = Camera.main;
        mainCameraTransform = mainCamera.transform;
        if (!character) character = transform;
        playerMovementPlane = new Plane(character.up, character.position + character.up * cursorPlaneHeight);
    }

    function Start() {
        screenMovementSpace = Quaternion.Euler(0, mainCameraTransform.eulerAngles.y, 0);
        screenMovementForward = screenMovementSpace * Vector3.forward;
        screenMovementRight = screenMovementSpace * Vector3.right;
    }

    function Update() {
        movementDirection = Input.GetAxis("Horizontal") * screenMovementRight + Input.GetAxis("Vertical") * screenMovementForward;
        if (movementDirection.sqrMagnitude > 1) movementDirection.Normalize();
        playerMovementPlane.normal = character.up;
        playerMovementPlane.distance = -character.position.y + cursorPlaneHeight;
        
        var cameraAdjustmentVector: Vector3 = Vector3.zero;
        cameraAdjustmentVector = facingDirection;
        
        var cursorWorldPosition: Vector3 = ScreenPointToWorldPointOnPlane(Input.mousePosition, playerMovementPlane, mainCamera);
        facingDirection = (cursorWorldPosition - character.position);
        facingDirection.y = 0;
    }

    public static
    function PlaneRayIntersection(plane: Plane,
    ray: Ray): Vector3 {
        var dist: float;
        plane.Raycast(ray, dist);
        return ray.GetPoint(dist);
    }

    public static
    function ScreenPointToWorldPointOnPlane(screenPoint: Vector3,
    plane: Plane,
    camera: Camera): Vector3 {
        var ray: Ray = camera.ScreenPointToRay(screenPoint);
        return PlaneRayIntersection(plane, ray);
    }

    function FixedUpdate() {

        // Handle the movement of the character
        var targetVelocity: Vector3 = movementDirection * walkingSpeed;
        var deltaVelocity: Vector3 = targetVelocity - rigidbody.velocity;
        if (rigidbody.useGravity) deltaVelocity.y = 0;
        rigidbody.AddForce(deltaVelocity * walkingSnappyness, ForceMode.Acceleration);

        // 設定玩家面對的方向,或如果是零,則(面對)運動方向
        var faceDir: Vector3 = facingDirection;
        if (faceDir == Vector3.zero) faceDir = movementDirection;
        // 使人物轉動朝著目標的旋轉
        if (faceDir == Vector3.zero) {
            rigidbody.angularVelocity = Vector3.zero;
        } else {
            var rotationAngle: float = AngleAroundAxis(transform.forward, faceDir, Vector3.up);
            rigidbody.angularVelocity = (Vector3.up * rotationAngle * turningSmoothing);
        }
    }

    // The angle between dirA and dirB around axis
    static function AngleAroundAxis(dirA: Vector3, dirB: Vector3, axis: Vector3) {
        // Project A and B onto the plane orthogonal target axis
        dirA = dirA - Vector3.Project(dirA, axis);
        dirB = dirB - Vector3.Project(dirB, axis);
        // Find (positive) angle between A and B
        var angle: float = Vector3.Angle(dirA, dirB);
        // Return angle multiplied with 1 or -1
        return angle * (Vector3.Dot(axis, Vector3.Cross(dirA, dirB)) < 0 ? -1 : 1);
    }

0 ♥:

張貼留言