• 如果你在游戏的开发中,想要控制主角的移动却又不想处理刚体的碰撞,那么Unity3D中的角色控制器组件CharacterController就可以满足你的要求了。它包含一些刚体的属性,比如,如果在一个添加了角色控制器组件的对象上...

               如果你在游戏的开发中,想要控制主角的移动却又不想处理刚体的碰撞,那么Unity3D中的角色控制器组件CharacterController就可以满足你的要求了。它包含一些刚体的属性,比如,如果在一个添加了角色控制器组件的对象上添加一个带有SimpleMove()函数的脚本,那么该对象的重力被自动应用,而且该对象的Y轴上的速度被忽略;而如果你想保留Y轴上的速度,不应用重力,则可使用角色控制器的Move()函数控制对象。好了,下面通过具体的例子来学习角色控制器CharacterController的使用方法。

           我们要实现的效果是我们的英雄在三个点之间来回直线运动,并且在到达某一点时实现转身的效果。

           首先新建一个工程,我们把需要的主角模型拖到场景中,主角模型可以从文章最后的工程下载后获得。我们把贴图拖到主角模型上,就出现了一个帅气的魔法师角色。然后我们新建一个平面Plane,三个空对象,命名为point1,point2,point3,并添加标识,还有在场景中加入一个Directional light灯光。完成之后的效果如下:

                       

             然后我们开始编写脚本代码,新建一个C#文件,重命名为“heroControl”,具体代码如下所示,注释都已添加。

    using UnityEngine;
    using System.Collections;
    
    public class heroControl : MonoBehaviour {
    
        //定义主角角色控制器
        CharacterController hero;
    
        //点数组
        public Transform[] points;
    
        //下一个点的下标,主角移动速度
        public int nextIndex;
        public int moveSpeed = 10;
    
        void Start()
        {
            //初始化主角移动速度
            nextIndex = 0;
            //获得主角的角色控制器组件
            hero = GetComponent<CharacterController>();
        }
        void Update()
        {
            //如果主角距离点的距离大于0.2,则算出主角的朝向,移动主角人物
            if (Vector3.Distance(ignoreY(points[nextIndex % points.Length].position), ignoreY(transform.position)) > 0.2f)
            {
                //主角的朝向即为下一个点坐标减去主角坐标的向量
                Vector3 direction = (ignoreY(points[nextIndex % points.Length].position) - ignoreY(transform.position)).normalized;
                //插值改变主角的朝向,使其有一个自然转向的过程,防止其瞬间转向
                hero.transform.forward = Vector3.Lerp(transform.forward, direction, 0.1f);
                //移动主角
                hero.SimpleMove(transform.forward * moveSpeed);
            }
            else
            {
                //如果到达点,则使下一点作为目标点
                nextIndex++;
            }
        }
        //这个函数用来取消向量的Y轴影响,比如主角的高度与点之间可能有一段距离,我们要忽略这段距离
        Vector3 ignoreY(Vector3 v3)
        {
            return new Vector3(v3.x, 0, v3.z);
        }
    }
    

           最后我们把脚本文件拖到主角模型上,然后别忘了把三个点拖到我们定义的点数组中

                    

          好了,运行程序,我们可以看到主角自己在三个点之间来回巡逻,并在到达某一点后转身继续向下一点运动,我们这里只是截图,所以看不出效果,请大家下载项目工程源码后运行查看效果。

                  


         项目源码下载地址:点此下载


    展开全文
  • Unity3D 控制角色 最简单的移动 脚本挂到需要控制的角色上 所在代码 对上述方法的说明 需求增加 控制使用的按键可自定义 增加平滑的功能 代码 增加一项Input Axis 名称为Rotate后 使用 Q 和 E 键旋转 整个平滑的...

    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

    展开全文
  • 以前转载了一篇关于在Unity3d中鼠标控制物体的旋转、移动、缩放的代码 然后发现错误比较多,就重新写了一个代码,自我感觉简单实用。。。特意分享出来供大家参考 原文章也贴出来吧 【Unity3d 鼠标滚动拉近模型、鼠标...

    一、前言

    以前转载了一篇关于在Unity3d中鼠标控制物体的旋转、移动、缩放的代码
    然后发现错误比较多,就重新写了一个代码,自我感觉简单实用。。。特意分享出来供大家参考
    原文章也贴出来吧
    【Unity3d 鼠标滚动拉近模型、鼠标右键旋转模型、鼠标中键拖拽模型】
    https://blog.csdn.net/q764424567/article/details/78630649

    效果图:
    在这里插入图片描述

    二、知识点

    • Input.GetMouseButton(0)
      获取鼠标输入,参数为一个int值
      为0的时候获取的是左键

    • Input.GetMouseButton(1)
      为1的时候获取的是右键

    • Input.GetMouseButton(2)
      为2的时候获取的是中键(就是那个滑轮)

    • Input.GetMouseButton
      鼠标按压

    • Input.GetMouseButtonUp
      鼠标点击

    • Input.GetMouseButtonDown
      鼠标松开

    • Camera.main.ScreenToWorldPoint
      屏幕坐标转化为世界坐标

    • Quaternion rotation = Quaternion.Euler(0, 0, 0);
      欧拉角转化为四元数

    三、代码分享

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class MouseControlModel : MonoBehaviour
    {
        //旋转最大角度
        public int yMinLimit = -20;
        public int yMaxLimit = 80;
        //旋转速度
        public float xSpeed = 250.0f;
        public float ySpeed = 120.0f;
        //旋转角度
        private float x = 0.0f;
        private float y = 0.0f;
    
        void Update()
        {
            if (Input.GetMouseButton(0))
            {
                //将屏幕坐标转化为世界坐标  ScreenToWorldPoint函数的z轴不能为0,不然返回摄像机的位置,而Input.mousePosition的z轴为0
                //z轴设成10的原因是摄像机坐标是(0,0,-10),而物体的坐标是(0,0,0),所以加上10,正好是转化后物体跟摄像机的距离
                Vector3 temp = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10));
                transform.position = temp;
            }
            else if (Input.GetMouseButton(1))
            {
                //Input.GetAxis("MouseX")获取鼠标移动的X轴的距离
                x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
                y = ClampAngle(y, yMinLimit, yMaxLimit);
                //欧拉角转化为四元数
                Quaternion rotation = Quaternion.Euler(y, x, 0);
                transform.rotation = rotation;
            }
            else if (Input.GetAxis("Mouse ScrollWheel") != 0)
            {
                //鼠标滚动滑轮 值就会变化
                if (Input.GetAxis("Mouse ScrollWheel") < 0)
                {
                    //范围值限定
                    if (Camera.main.fieldOfView <= 100)
                        Camera.main.fieldOfView += 2;
                    if (Camera.main.orthographicSize <= 20)
                        Camera.main.orthographicSize += 0.5F;
                }
                //Zoom in  
                if (Input.GetAxis("Mouse ScrollWheel") > 0)
                {
                    //范围值限定
                    if (Camera.main.fieldOfView > 2)
                        Camera.main.fieldOfView -= 2;
                    if (Camera.main.orthographicSize >= 1)
                        Camera.main.orthographicSize -= 0.5F;
                }
            }
        }
    
        //角度范围值限定
        static float ClampAngle(float angle, float min, float max)
        {
            if (angle < -360)
                angle += 360;
            if (angle > 360)
                angle -= 360;
            return Mathf.Clamp(angle, min, max);
        }
    }
    
    

    谢谢大家!

    展开全文
  • Unity3D 角色转向和自动跟随通过挂载脚本控制3D人物的移动和转向,先上一个官方的例子:这里只有转向而没有移动的方法,看了下原工程,移动是做在动画中的,只要执行了动画就会跟着移动,而且每迈出一步的距离是固定...

    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;
            }
        }
    }
    
    展开全文
  • 文章Unity3D学习笔记04:角色控制器CharacterController控制人物移动旋转 的项目源码,免费下载。
  • 原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:【119706192】本文链接地址: Unity3D 控制物体移动、旋转、缩放 Transform基本移动函数: 1.指定方向移动: //移动速度 float ...

    原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:【119706192本文链接地址: Unity3D 控制物体移动、旋转、缩放

    Transform基本移动函数:

    1.指定方向移动:

    //移动速度 
    float TranslateSpeed = 10f;
    
    //Vector3.forward 表示“向前”
    transform.Translate(Vector3.forward *TranslateSpeed);
    

    2.全方向移动:

    复制代码
    //x轴移动速度移动速度 
    float xSpeed = -5f;
    
    //z轴移动速度移动速度 
    float  zSpeed = 10f;
    
    //向x轴移动xSpeed,同时想z轴移动zSpeed,y轴不动 
    transform.Translate(xSpeed,0,zSpeed);
    
    复制代码

    3.重置坐标:

    //x轴坐标 
    float xPostion = -5f;
    //z轴坐标 
    float zPostion = 10f;
    //直接将当前物体移动到x轴为xPostion,y轴为0,z轴为zPostion的三维空间位置。
    transform.position = Vector3(xPostion,0,zPostion);

    输入控制:

    1.输入指定按键:

    复制代码
    //按下键盘“上方向键”
    if(Input.GetKey ("up"))
      print("Up!");
    
    //按下键盘“W键”
    if(Input.GetKey(KeyCode.W);)
      print("W!");
    复制代码

    2.鼠标控制

    //按下鼠标左键(0对应左键 , 1对应右键 , 2对应中键) 
    if(Input.GetMouseButton(0))
      print("Mouse Down!");
    Input.GetAxis("Mouse X");//鼠标横向增量(横向移动) 
    Input.GetAxis("Mouse Y");//鼠标纵向增量(纵向移动)

    3.获取轴:

    //水平轴/垂直轴 (控制器和键盘输入时此值范围在-1到1之间)
    Input.GetAxis("Horizontal");//横向 
    Input.GetAxis ("Vertical");//纵向

    按住鼠标拖动物体旋转和自定义角度旋转物体:

     

    复制代码
    float speed = 100.0f;
    float x;
    float z;
    
    void Update () {
      if(Input.GetMouseButton(0)){//鼠标按着左键移动 
        y = Input.GetAxis("Mouse X") * Time.deltaTime * speed;               
        x = Input.GetAxis("Mouse Y") * Time.deltaTime * speed; 
      }else{
        x = y = 0 ;
      }
      
      //旋转角度(增加)
      transform.Rotate(new Vector3(x,y,0));
      /**---------------其它旋转方式----------------**/
      //transform.Rotate(Vector3.up *Time.deltaTime * speed);//绕Y轴 旋转 
    
      //用于平滑旋转至自定义目标 
      pinghuaxuanzhuan();
    }
    
    
    //平滑旋转至自定义角度 
    
    void OnGUI(){
      if(GUI.Button(Rect(Screen.width - 110,10,100,50),"set Rotation")){
        //自定义角度
    
        targetRotation = Quaternion.Euler(45.0f,45.0f,45.0f);
        // 直接设置旋转角度 
        //transform.rotation = targetRotation;
    
        // 平滑旋转至目标角度 
        iszhuan = true;
      }
    }
    
    bool iszhuan= false;
    Quaternion targetRotation;
    
    void pinghuaxuanzhuan(){
      if(iszhuan){
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 3);
      }
    }
    复制代码

     

     

     

     

     

    键盘控制物体缩放:

    复制代码
    float speed = 5.0f;
    float x;
    float z;
    
    void Update () {
        x = Input.GetAxis("Horizontal") * Time.deltaTime * speed;    //水平           
        z = Input.GetAxis("Vertical") * Time.deltaTime * speed;      //垂直//"Fire1","Fine2","Fine3"映射到Ctrl,Alt,Cmd键和鼠标的三键或腰杆按钮。新的输入轴可以在Input Manager中添加。
        transform.localScale += new Vector3(x, 0, z);  
        
        /**---------------重新设置角度(一步到位)----------------**/
        //transform.localScale = new Vector3(x, 0, z);
    }
    展开全文
  • Unity3d角色控制

    2016-04-10 13:51:28
    我们要控制角色的移动,可以全部细节都由自己来实现。控制角色模型的移动,同时移动摄影机,改变视角。当然Unity也提供了一些组件,可以让我们做更少的工作,实现我们所期望的功能。今天我们就一起系统来学习相关的...
  • 在上一篇文章[Unity3D]Unity3D游戏开发之角色控制漫谈>一文中,博主与大家分享自己在角色控制方面的一些感悟。今天呢,我们继续来探讨Unity3D角色控制的内容,今天博主将解决在上一篇文章中没有解决的问题,即自由...
  • Unity使用鼠标旋转缩放平移视角 用代码在Game界面完美实现Scene界面的操作方法。 使用方法:把脚本挂在相机上,把跟踪的target拖到脚本上。 视角跟踪的是一个空物体,当然如果你是做RPG游戏需要跟踪某一角色的视角...
  • using System.Collections; using System.Collections.Generic; using UnityEngine; public class Driver : MonoBehaviour { Animator anim; float speed = 5f; float rotationSpeed = 100f;... priv...
  • <title>Unity3D Player角色移动控制脚本</title> Unity3D Player角色移动控制脚本 1. 简介 在Unity3D中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position。我针对角色...
  • 王者荣耀在现在看来可能已经成为不少人每天都会打开一款软件,角色控制及其操作方式简单,使其短时间内获得了大量的玩家喜爱和追捧。 可以很明显的看到王者荣耀的操作方式就是虚拟摇杆,可以控制人物的的移动,...
  • 在游戏中我们通常要控制玩家的移动和旋转 首先我们说一下移动: 移动的本质就是在Update()或LateUpdate()中不断修改物体的position来实现移动,移动的方法有4中: (1):transform.Translate()第一种方法...
  • 控制角色移动,对于PC端而言就是键盘或者鼠标。其中键盘控制角色移动的是经典的fps游戏中wasd四个方向按键。而鼠标控制角色移动一般常见于MMORPG。我比较倾向于MMORPG风格控制角色移动,所以选择这一类。 Unity3D...
  • using UnityEngine; using System.Collections; public class MoveObj : MonoBehaviour {  float speed = 10.0f; //移动速度 ... //旋转速度  // Update is called once pe
  • 各位朋友,大家好,我是秦元培,欢迎大家关注我的博主,我的博客地址是blog.csdn.net/...本文采用的方法依然是在[Unity3D]Unity3D游戏开发之自由视角下的角色控制这篇文章中所采用的方法,所以如果大家对于这部
  • using UnityEngine; public class NewBehaviourScript : MonoBehaviour { private Vector3 nowPos; private Vector3 oldPos; private bool isClick = false;... public float length = 1;... priva...
  • 在写第三人称控制的时候,一开始在电脑测试是用WASD控制角色 更多精彩请关注【狗刨学习网】   后来需要发布到手机上,于是就加了一个摇杆   键盘控制角色的代码已经写好了,角色八方向移动   如果按照传统...
  • Unity3D 虚拟遥感角色控制 Unity3D 虚拟遥感角色控制, 基于UGUI 没有使用插件; 并且映射键盘 用于编辑状态下的 调试 Unity3D 版本 :Unity 2018.4.20f1 (64-bit) 这次待业在准备 ,做个小的 APG 游戏, ...
  • 摄像机开始跟随角色 CameraMMO.CameraFollow(gameObject, GameObject.FindGameObjectWithTag("Player").transform, Camera.main.transform).enabled = true; //不跟随则相反 CameraMMO.CameraFollow(gameObject, ...
1 2 3 4 5 ... 20
收藏数 2,456
精华内容 982