查看: 890|回复: 0
打印 上一主题 下一主题

[其他] 实现物体绕不同轴旋转,并可以外部调用的函数

[复制链接]

1557

主题

1

听众

1万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
454
精华
31

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2013-10-15 15:17:28 |只看该作者 |倒序浏览
第一个文件,声明枚举类型,分别为均匀变化和加速变化

using UnityEngine;
using System.Collections;

public enum CTRotationType
{
    Uniform,
    AccelerateUniformly
}

第二个文件:主函数,实现围绕轴变化的两个函数,分别为均匀变化和加速变化

using UnityEngine;
using System.Collections;

public class CTRotation : MonoBehaviour {

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
        if (isRotating)
        {
            executeRotate();
        }
    }

    bool isRotating = false;

    Quaternion definedRotation = new Quaternion(0, 0, 0,0);

    Vector3 rotateVector = new Vector3(1,0,0);

    float rotateVelocity = 0;

float accelerateDuration = 0;
float leftDuration = 0;
float rotateDuration = 0;

    int rotateAxis = 0;
float angleRange = 0;
float deltaRotate = 0;//0;


// acceleration when it is in the accelerating process.
    float rotateAcceleration = 0;

    CTRotationType rotateType;

//int RotateType = 0;

    private void initRotateArgument( float _initAngleRange, int _initRotateAxis, float _initRotateDuration)
    {
  rotateAxis = _initRotateAxis;
        rotateDuration = _initRotateDuration;
        leftDuration = _initRotateDuration;
  angleRange = _initAngleRange;
  rotateType = CTRotationType.Uniform;
    }

    public void RotateTo(float _angleRange, int _axis, float _duration)
    {
  print("in the rotateto");
        isRotating = false;
        rotateType = CTRotationType.Uniform;
  //RotateType = 0;

  initRotateArgument(_angleRange, _axis, _duration);

  switch(rotateAxis)
  {
   case 0: //rotate around X axis
   {
    rotateVector = Vector3.right;
    break;
   }
   case 1://rotate around Y axis
   {
    rotateVector = Vector3.up;
    break;
   }
   case 2://rotate around Z axis
   {
    rotateVector = Vector3.forward;
    break;
   }
   default:
    break;
  }

  deltaRotate = angleRange/rotateDuration;

        isRotating = true;
    }

    public void RotateTo(float _angleRange, int _axis, float _duration, float _accelerateDuration)
    {
        isRotating = false;
        rotateType = CTRotationType.AccelerateUniformly;
  //RotateType = 1;

  rotateAcceleration = 1/((rotateDuration - accelerateDuration)*accelerateDuration);
        initRotateArgument(_angleRange, _axis, _duration);

  switch(rotateAxis)
  {
   case 0: //rotate around X axis
   {
    rotateVector = Vector3.right;
    break;
   }
   case 1://rotate around Y axis
   {
    rotateVector = Vector3.up;
    break;
   }
   case 2://rotate around Z axis
   {
    rotateVector = Vector3.forward;
    break;
   }
   default:
    break;
  }

        accelerateDuration = _accelerateDuration;

     //   deltaRotate = angleRange/(_duration - _accelerateDuration*2);

        isRotating = true;
    }

    void executeRotate()
    {
        switch (rotateType)
        {
            //case 0://CTMoveType.Uniform:
   case CTRotationType.Uniform:
                uniformRotate();
                break;

            //case 1://CTMoveType.AccelerateUniformly:
   case CTRotationType.AccelerateUniformly:
                accelerateRotate();
                break;
        }

        leftDuration -= Time.deltaTime;
       /* if (leftDuration <= 0)
        {
            transform.position = targetPosition;
            isMoving = false;
        }*/
    }

    private void accelerateRotate()
    {
  print(leftDuration);
        if (leftDuration > (rotateDuration - accelerateDuration))
        {
   rotateVelocity = (float)((angleRange*(rotateDuration - leftDuration))*rotateAcceleration);
          //  transform.Rotate(rotateVelocity * Time.deltaTime*rotateVector, Space.World);
   transform.Rotate(rotateVelocity * rotateVector*Time.deltaTime, Space.World);
        }
        else if (leftDuration > accelerateDuration)
        {
   rotateVelocity = (float)((angleRange*accelerateDuration)*rotateAcceleration);
            transform.Rotate(rotateVelocity*rotateVector*Time.deltaTime, Space.World);
        }
        else if (leftDuration > 0)
        {
   rotateVelocity= (float)((angleRange*leftDuration)*rotateAcceleration);
   transform.Rotate(rotateVelocity*rotateVector*Time.deltaTime, Space.World);
        }
  else
   isRotating = false;
    }

    private void uniformRotate()
    {
  print(leftDuration);
  //if(leftDuration)
  if(leftDuration > 0)
  {
   transform.Rotate(rotateVector*deltaRotate*Time.deltaTime, Space.World);
   //transform.Rotate(rotateVector * Time.deltaTime*deltaRotate, Space.World);
  }
  else
   isRotating = false;
    }
}

第三个文件,测试脚本

using UnityEngine;
using System.Collections;

public class TestRotationScript : MonoBehaviour {

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {

}

void OnGUI ()
    {
  CTRotation ttscript;
  CTChangeAlpha colorScript;
  GameObject testObject = GameObject.Find("TestCube");
        //Component testObjectScript = testObject.GetComponent("CRotation");
        ttscript = (CTRotation)testObject.GetComponent("CTRotation");
  colorScript = (CTChangeAlpha)testObject.GetComponent("CTChangeAlpha");

   if (GUI.Button (new Rect (20,40,80,20), "UniRotate")) {
       ttscript.RotateTo(3600f, 2, 2f);
  }

   if(GUI.Button(new Rect(20,60,80,20),"AccRotate")){
  ttscript.RotateTo(3600f, 2, 2f, 0.5f);
   }

    if(GUI.Button(new Rect(20,80,80,20),"Color")){
     colorScript.ColorTo(2,5.0f);
    }
    }
}
其中:第一个和第二脚本赋给目标物体;第三个脚本赋给任何一个物体作为测试物体使用
代码目的是方便外部调用和函数重用;注意isRotating参数的使用

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-9-20 17:55 , Processed in 0.081821 second(s), 28 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部