2018-07-02 12:03:06 coldwind811201 阅读数 4710

Unity3D 控制角色(一)

最简单的移动 脚本挂到需要控制的角色上

    public float MoveSpeed = 15.0f;
    public float RotateSpeed = 80.0f;

    void Update () {
        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
        {
            transform.Translate(0, 0, 1 * MoveSpeed * Time.deltaTime, Space.Self);
        }
        if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
        {
            transform.Translate(0, 0, -1 * MoveSpeed * Time.deltaTime, Space.Self);
        }
        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
        {
            transform.Translate(-1 * MoveSpeed * Time.deltaTime, 0, 0, Space.Self);
        }
        if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
        {
            transform.Translate(1 * MoveSpeed * Time.deltaTime, 0, 0, Space.Self);
        }


        if (Input.GetKey(KeyCode.Q))
        {
            transform.Rotate(0, -1 * RotateSpeed * Time.deltaTime, 0, Space.Self);
        }
        if (Input.GetKey(KeyCode.E))
        {
            transform.Rotate(0, 1 * RotateSpeed * Time.deltaTime, 0, Space.Self);
        }
    }

所在代码

ControlCharacter001.cs

对上述方法的说明

  • 方法直接操作对象的tranform组件
  • 写在Update中每帧调用
  • translate中的三个坐标值表示的是相对当前位置的位移向量 位移(距离)=速度*时间 时间则是time.deltaTime(单位是秒 表述的是从上一帧到本帧经过的时间 是变化的 速度的单位是米每秒)
  • 对外部暴露2个速度变量可修改(移动和旋转)
  • Time.deltaTime用于协调线性,保证帧与帧之间速度一致,因为帧间隔随机器性能不同,使用Time.deltaTime可以保证是匀速运动
  • 不使用Time.deltaTime的后果是在前端表现出卡顿 速度虽然可以通过2个公有变量进行调整
    关于Time.deltaTime参看 https://blog.csdn.net/wdjhzw/article/details/73433658?locationNum=7&fps=1

需求增加

  • 按键需要可以修改

控制使用的按键可自定义 增加平滑的功能

使用Input,按键不再使用KeyCode这种方式
使用按键轴名定义 Axis
参数位置 Edit -> Project Settings -> Input
这里写图片描述

  • 可以增加自定义轴名称
  • 一个功能分为正向和反向(Negative->反向 Positive->正向)
  • 有第2按键的功能(Alt部分)
  • 平滑的功能(Gravity Dead) 使用GetAxis可以得到平滑滤波的值
  • 使用GetAxisRaw则依然是 -1 0 1三个值
  • 使用GetAxis对应按下键有一个逐渐增加到1的过滤 放开按键逐渐变回0
    这里写图片描述

Positive Button:使用GetButton()时,引用的字符串名
Gravity:使用GetAxis()时,返回0的速度,越大越快
Sensitivity:使用GetAxis()时,达到1或-1的速度,越大越快
Dead:当使用摇杆时,当Dead越大需要移动越大的距离才会有返回值(当不需要过小的返回值时使用)
snap:使用GetAxis()时,如果勾选,正反按键同时按下会返回0

导出后的项目可以给用户修改按键

这里写图片描述

代码

    public float MoveSpeed = 15.0f;
    public float RotateSpeed = 80.0f;

    void Update () {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        //Debug.Log(string.Format("h: {0} v: {1}", h, v));

        transform.Translate(h * MoveSpeed * Time.deltaTime, 0, v * MoveSpeed * Time.deltaTime, Space.Self);
    }

增加一项Input Axis 名称为Rotate后 使用 Q 和 E 键旋转

这里写图片描述

    public float MoveSpeed = 15.0f;
    public float RotateSpeed = 80.0f;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        float r = Input.GetAxisRaw("Rotate");

        //Debug.Log(string.Format("h: {0} v: {1}", h, v));

        transform.Translate(h * MoveSpeed * Time.deltaTime, 0, v * MoveSpeed * Time.deltaTime, Space.Self);
        transform.Rotate(0, r * RotateSpeed * Time.deltaTime, 0, Space.Self);
    }

整个平滑的过程

按下按键 值从0逐渐变为1 放开按键从1逐渐变回0
变化的量由Gravity

这里写图片描述

效果 起步和停止都有一个缓冲

这里写图片描述

如果使用GetAxisRaw替换GetAxis则没有缓冲效果
参看 https://blog.csdn.net/cui240558023/article/details/50448013?_t=t

2014-11-24 21:00:13 li460998973 阅读数 13046

    移动设备游戏中经常会遇到重力感应的开发,Unity简化了重力感应的开发, 通过访问Input.acceleration属性,取回加速度传感器的值。首先我们看一下重力传感器的方向问题。Unity3D中重量的取值范围是 -1.0 到 +1.0.


X轴:home按键在下手机面朝天向右旋转90度重力分量为+1.0  向左旋转90度重力分量为-1.0

Y轴:home按键在上手机背朝自己重力分量为+1.0 home按键在下手机面朝自己重力分量为-1.0

Z轴:手机面朝地面重力分量为+1.0 手机面朝天空重力分量为-1.0


方向如下图所示。



unity中使用Input.acceleration的x,y,z属性即可获得重力分量:

Input.acceleration.x; 重力感应X轴的重力分量

Input.acceleration.y; 重力感应Y轴的重力分量

Input.acceleration.z; 重力感应Z轴的重力分量

下面我们使用脚本来掩饰重力感应效果,分别控制贴图移动和方块移动。


public class mono4 : MonoBehaviour {
     public Texture texture;//贴图,在Inspector中指定
     private float x,y;//贴图的坐标
     public float speed = 10.0F;//方块移动速度
    void Update() {
          //以下控制方块移动
        Vector3 dir = Vector3.zero;//方块移动向量
        dir.x = -Input.acceleration.y;
        dir.z = Input.acceleration.x;
        if (dir.sqrMagnitude > 1)
            dir.Normalize();
        dir *= Time.deltaTime;
        transform.Translate(dir * speed);
    
          //以下控制贴图移动
          x += Input.acceleration.x * 30;
              y += -Input.acceleration.y * 30;  

             //避免小球超出屏幕
             if(x < 0){
                 x = 0;
             }else if(x > Screen.width-50){
                 x = Screen.width-50;
             }
              if(y < 0){
             y = 0;
             }else if(y > Screen.height-50){
             y = Screen.height-50;
        }

    }
     void OnGUI(){
          //将重力分量打印出来
          GUI.Label(new Rect(100,100,100,100),"x="+Input.acceleration.x+"   y="+Input.acceleration.y+"   z="+Input.acceleration.z);
          //绘制贴图
          GUI.DrawTexture(new Rect(x,y,50,50),texture); 
     }
}



在Android真机上测试如下:





2015-11-20 16:58:09 fenrir_sun 阅读数 6146

Unity3D 角色转向和自动跟随

通过挂载脚本控制3D人物的移动和转向,先上一个官方的例子:

这里写图片描述

这里只有转向而没有移动的方法,看了下原工程,移动是做在动画中的,只要执行了动画就会跟着移动,而且每迈出一步的距离是固定的。如果移动没有做在动画里只要像旋转一样添加一个位移的变化就行了,下面是自己的例子:

代码块

以下例子仅记录下大致的方法,尚需测试,这里可以处理多个按键同时按下的情况:

using UnityEngine;

public class MoveInput
{
    bool presskey ;

    void Update() 
    {
        presskey = false;
        if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer)
        {

            bool keyboard = true;
            if (keyboard)
            {
                int x = 0;
                int y = 0;
                if (Input.GetKey(KeyCode.A))
                {
                    x -= 1;
                }
                if (Input.GetKey(KeyCode.D))
                {
                    x += 1;
                }
                if (Input.GetKey(KeyCode.S))
                {
                    y -= 1;
                }
                if (Input.GetKey(KeyCode.W))
                {
                    y += 1;
                }
                if (!GameApp.Instance().IsAutoFight() || x!=0 || y!=0 || NoTarget())
                {
                    bAutomove = false;
                    Dir2 = new Vector2(x, y);
                }
                if (x != 0 || y != 0)
                {
                    presskey = true;
                    PlayerMove(Dir2);
                }
            }
        }
    }

    void PlayerMove(Vector2 direction)
    {
        float offsetX = direction.x * Time.deltaTime * _moveToSpeed;
        float offsetY = direction.y * Time.deltaTime * _moveToSpeed;
        transform.position = new Vector3(transform.position + offsetX , 0, transform.position + offsetY );
    }
}

有时候会有一些自动跟随的需要,比如宠物跟着主角走,思路就是将主角的空间位置设置为移动目标,通过update里的迭代去接近目标,朝向也是同样处理,朝向上的接近使用:Quaternion.Slerp(self.transform.rotation, target.transform.rotation, Time.deltaTime * dirSpeed);
移动上的接近使用:Vector3.MoveTowards(self.transform.position, target.transform.position, Time.deltaTime * moveSpeed);
如果要让跟随更自然一些,可以在主角移动,每次转向的时候传给宠物一个目标,宠物按顺序将这些目标位置存放在一个列表里,按照列表里的顺序移动,就像重走了一遍主角的路线一样。

代码块

宠物跟随示例,这里仅展示下大致方法:

using UnityEngine;

public class PetMovement : BaseMovement
{
    void Update()
    {
        Player ownerPlayer = pet.OwnerPlayer;
        GameObject target = GetTarget(ownerPlayer );
        if (target != null)
        {
            float distance = Vector3.Distance(transform.position, target.transform.position);
            PetInfo petInfo = GetPetInfo(pet.ID);
            var dir = target.transform.position - transform.position;
            int skillRange = petInfo.skillRange;
            if (skillRange < distance) //  当和主人之间的距离超过技能距离时跟随
            {
                Action.ChangeAction(CAction.RunFront);// 改变动画
                var destPos = transform.position + dir.normalized * (distance - skillRange + 1);
                transform.position = Vector3.MoveTowards(transform.position, destPos, Time.deltaTime * move_Speed);
            }
            var rotation = Quaternion.LookRotation(dir); //  获得 目标方向
            transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 5);  // 差值  宠物朝向趋向目标
            return;
        }
    }
}
2018-07-17 22:38:00 weixin_30236595 阅读数 15

Unity3d常用按键和组合键:

1.鼠标左键:选中物体

2.鼠标中键:平移视角,和手型功能一样

3.鼠标右键:旋转观察角度

4.Alt+鼠标左键:旋转观察角度

5.Alt+鼠标右键:拉远拉近

 

转载于:https://www.cnblogs.com/tthjHiroki/p/9326433.html

2017-08-19 21:07:56 blanrey 阅读数 359
    void Gui()
    {
        //在屏幕左上为原点(20,20)位置创建一个长100宽80的摁扭“Q_X”
        if (GUI.Button(new Rect(20,20,100,80),"Q_X"))
        {
            Quaternion q = Quaternion.identity;
            //使物体沿世界x轴顺时针旋转30度
            q.eulerAngles = new Vector3(30, 0, 0);
            transform.rotation = q * transform.rotation;
        }
        //同样,我们给摁扭与摁扭之间留出五个像素点,也就是在(20,105)位置创建一个长100宽80的摁扭“Q_Y”
        if (GUI.Button(new Rect(20, 105, 100, 80), "Q_Y"))
        {
            Quaternion q = Quaternion.identity;
            //使物体沿世界y轴顺时针旋转30度
            q.eulerAngles = new Vector3(0, 30, 0);
            transform.rotation = q * transform.rotation;
        }
        //以下同理
        if (GUI.Button(new Rect(20, 190, 100, 80), "Q_Z"))
        {
            Quaternion q = Quaternion.identity;
            //使物体沿世界z轴顺时针旋转30度
            q.eulerAngles = new Vector3(0, 0, 30);
            transform.rotation = q * transform.rotation;
        }


        if (GUI.Button(new Rect(125, 20, 100, 80), "V_X"))
        {
            //第二种方法,使物体沿世界x轴逆时针旋转30度
            transform.eulerAngles += new Vector3(30,0,0);
        }
        if (GUI.Button(new Rect(125, 105, 100, 80), "V_Y"))
        {
            //使物体沿世界y轴逆时针旋转30度
            transform.eulerAngles += new Vector3(0, 30, 0);
        }
        if (GUI.Button(new Rect(125, 190, 100, 80), "V_Z"))
        {
            //使物体沿世界z轴逆时针旋转30度
            transform.eulerAngles += new Vector3(0, 0, 30);
        }
    }

这里写图片描述

unity旋转向量

阅读数 6282

没有更多推荐了,返回首页