unity学习--003:角色控制器

今天研究模型控制器,探寻下怎么实现基本的控制模型方法

  首先,我随便拉了几个小模型

    

这就是猪脚了。先添加常用的前后左右,就是WSAD,按wsad就使角色的transform组件变化下位置,

   private float MoveSpeed = 3f;
    void Start()
    {

    }

    void Update()
    {

        if(Input.GetKey(KeyCode.A))
        {        //改变角色X轴
            transform.Translate(Vector3.right * -MoveSpeed * Time.deltaTime, Space.World);
        }
        if(Input.GetKey(KeyCode.D))
        {
            transform.Translate(Vector3.right * MoveSpeed * Time.deltaTime, Space.World );
        }
        if (Input.GetKey(KeyCode.W))
        {           //改变角色Y轴
            transform.Translate(Vector3.forward * MoveSpeed * Time.deltaTime, Space.World);
        }
        if (Input.GetKey(KeyCode.S))
        {
            transform.Translate(Vector3.forward * -MoveSpeed * Time.deltaTime,Space.World);
        }

    }

啊,现在那个兽人应该可以前后左右移动了,这里是通过改变角色的transform的position来实现的(其实是废话,都是通过改变这个的,大家懂我的意思就好),

换种思路,我先给个目标点,让角色平移过去

private float MoveSpeed = 6f;
    void Update()
    {
        Vector3 targetPos = transform.position;
         if(Input.GetKey(KeyCode.A))
        {
            targetPos.Set(targetPos.x-MoveSpeed * Time.deltaTime,targetPos.y,targetPos.z);
        }
        if(Input.GetKey(KeyCode.D))
        {
            targetPos.Set(targetPos.x+MoveSpeed * Time.deltaTime,targetPos.y,targetPos.z);
        }
        if (Input.GetKey(KeyCode.W))
        {

            targetPos.Set(targetPos.x,targetPos.y,targetPos.z+MoveSpeed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.S))
        {
           targetPos.Set(targetPos.x,targetPos.y,targetPos.z-MoveSpeed * Time.deltaTime);
        }

        transform.position = Vector3.Lerp(transform.position, targetPos, MoveSpeed * Time.deltaTime);
    }

这是两种移动的方式,暂时只想到两种移动方式,若有其他的回复我。

除了移动方式,方向也是要考虑的,在第一种移动方式中,如何设置角色的朝向呢? 我是这样考虑的,得到移动前的位置和移动后的位置,相减获得方向,啊,我竟聪明如斯,动手

 private float MoveSpeed = 3f;

    void Start()
    {

    }

    void Update()
    {
        //获取移动前位置
        Vector3 lastPosation = transform.position;
        if(Input.GetKey(KeyCode.A))
        {
            transform.Translate(Vector3.right * -MoveSpeed * Time.deltaTime);
        }
        if(Input.GetKey(KeyCode.D))
        {
            transform.Translate(Vector3.right * MoveSpeed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.W))
        {
            transform.Translate(Vector3.forward * MoveSpeed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.S))
        {
            transform.Translate(Vector3.forward * -MoveSpeed * Time.deltaTime);
        }
        //设置方向
        transform.LookAt(transform.position+ transform.position-lastPosation);
    }

然后,老鸟该呵呵一笑了

截图看不出效果,如果按照我的代码,这个小人是会原地转圈,看上去很白痴。

........

省略号代表我想了很长时间,然后看了unityAPI

public class example : MonoBehaviour {
	void Update() {
		transform.Translate(Vector3.forward * Time.deltaTime);
		transform.Translate(Vector3.up * Time.deltaTime, Space.World);
	}
}

原来是坐标系的问题,Space.World ,不过我原来一直没考虑这个问题啊,好像也能实现移动?

想了会,原来移动的时候,这兽人脸是不变方向的。所以他移动的时候不考虑方向也行。现在兽人的朝向要变了,自身坐标系就一直在转变,所以要加上世界坐标系

  这样这个兽人终于不用走太空步了。

那移动的第二个方法如何做方向,应该只要看向目标点就行了吧,回顾下这个移动的代码,不像自身坐标系,添加

 transform.LookAt(targetPos + targetPos-transform.position);

这里的获取awsd的按键事件可以通过unity的API ,Input.GetAxis()来代替

private float MoveSpeed = 3f;

    void Start()
    {

    }

    void Update()
    {
        //获取移动前位置
        Vector3 lastPosation = transform.position;
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        transform.Translate(new Vector3(h, 0, v) * MoveSpeed * Time.deltaTime,Space.World);
        /*
        if(Input.GetKey(KeyCode.A))
        {
            transform.Translate(Vector3.right * -MoveSpeed * Time.deltaTime, Space.World);
        }
        if(Input.GetKey(KeyCode.D))
        {
            transform.Translate(Vector3.right * MoveSpeed * Time.deltaTime, Space.World );
        }
        if (Input.GetKey(KeyCode.W))
        {
            transform.Translate(Vector3.forward * MoveSpeed * Time.deltaTime, Space.World);
        }
        if (Input.GetKey(KeyCode.S))
        {
            transform.Translate(Vector3.forward * -MoveSpeed * Time.deltaTime,Space.World);
        }
         * */
        //设置方向
        transform.LookAt(transform.position+ transform.position-lastPosation);

    }

瞬间感觉清爽了,处女座的福音,而且可以发现角度不像原来的只能45度角变化,移动也平滑了,总之腰不痛,腿不酸,能上六楼了

Input.GetKey()方法通过参数的不同也能获得鼠标与触屏的输入类容,实际上我对这种方法,还有类似的invoke()方法,通过字符串调用其他方法的方式我很有兴趣,以后会去看看这种方法的实现原理与优劣。常用的pc玩游戏的操作方式还有鼠标,我来看看鼠标点击是怎么移动的,鼠标移动监听他右击时间,这个点是一个三维坐标,但屏幕是2d的,我这想了一会,结合我多年游戏经验,他么鼠标点的地方最后都是在地面上有木有,所以这里应该是将这个点给弄到地面上,想不明白鼠标点击点是2d的怎么转换为3D呢,首先排除添加默认Y=0 (x,0,z),然后大家请看

虽然有点抽象,但透露着浓浓的后现代艺术气息,A是屏幕,B是虚拟的地面,C是鼠标点,做过C于A面的法线交C面的点应该就是点击在地面上的点了,无论是平行还是交叉的游戏,法线应该都适用.先看看鼠标右击会得到什么吧。

结果,什么玩意儿都没得到,坑爹。看看API怎么说的
  • C#
  • JavaScript
using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
	public float horizontalSpeed = 2.0F;
	public float verticalSpeed = 2.0F;
	void Update() {
		float h = horizontalSpeed * Input.GetAxis("Mouse X");
		float v = verticalSpeed * Input.GetAxis("Mouse Y");
		transform.Rotate(v, h, 0);
	}
}
// Performs a mouse look.
//执行一个鼠标观察
var horizontalSpeed : float = 2.0;
var verticalSpeed : float = 2.0;
function Update () {
	// Get the mouse delta. This is not in the range -1...1
	//获取鼠标增量,范围不在-1...1
	var h : float = horizontalSpeed * Input.GetAxis ("Mouse X");
	var v : float = verticalSpeed * Input.GetAxis ("Mouse Y");
	transform.Rotate (v, h, 0);
}
javascript才有注释 ,才是亲儿子。  看到注释没,获取鼠标增量。然后我用鼠标划了下屏幕。然后看到参数和模型角度的变化

     

  这个值是有时候能看到 有事后看不到的,本着科研的精神,我进行了细致的控制变量法研究,发现要想看到X和Y有数据得鼠标划的快,而且有数据后会调用update三次左右。事情的真相如何,请看今晚的unity的不归路  OK,现在揭秘,这个XY确实是鼠标在一帧中的滑动向量,而调用update三次是因为手抖了:d  各位看官,我也是受害者,别吐槽。虽然这里花了点时间,但也不是做无用功,至少以后做镜头的旋转什么的就有方法了。  我觉得这里的向量获得方式也是获取一帧前的鼠标位置和一帧后的鼠标位置,然后获取的向量,一帧的时间很短,可以认为在一帧内几乎不可能双击造成误判,当然也可以在其中进行判断鼠标时候双击。  在有的游戏中鼠标点击即可能触发的是点击事件也肯能是拖动时间,就像我想点击文件时,如何判定是拖动还是单击,1 判断鼠标点击和放开的位置 2.判断鼠标点击和放开的时间想了会 这里显然是时间比较合理啊,比如鼠标拖出去再拖回原地这个显然1不能满足。暂时只能想到时间。  至于我为什么提出这两个问题,因为拖动和单机的区别就在于鼠标的位置和时间,请叫我 柯南.道尔.本。  说到这里,前面获取键盘的Input.GetAxis方法显然也是获取增量,键盘总不能得到在屏幕上的位置吧,这里估计是为了统一所以鼠标也获得的是增量。   扯了半天,还是没找到鼠标单击时的点。既然Input.GetAxis("Mouse Y")这个方法能获得向量,那应该也有获取位置的方法,总不能叫我们监听串口去吧。   在找inputAPI,我看到了这个Input.mousePosition,以我四级430的高分段选手来看,这一定是鼠标的位置,我们Debug.Log(Input.mousePosition)出鼠标的位置看看

    

这些点貌似都是Z轴为0的 屏幕的位置,我再点几个点,四角和中间的试试

可以看出,这个点的位置是以左下角为原点,以像素为坐标,比如我是1920*1080的屏幕,就和这个坐标系很吻合。这样就算获得了鼠标在屏幕上的位置,如何投射到scene中呢?再次有请抽象一号和二号

      

  第一幅图中A是显示器 B是场景 。 第二幅图中红色框是显示器,注意那个相机,屏幕相当于在中间截取了一面,那个A点就相当于鼠标点,屏幕上显示的就是摄像机与A点的射线,看到的东西,A点坐标我们获取到了就是mouseposition,但这个坐标是相对坐标,是相对于左下角的二维坐标,根据相机的位置可以获得相机的世界坐标点

在更具第二排的角度,rotation, 便可获得一个锥形,可以看上面的抽象2,屏幕应该是在固定位置中间或者1/3或者其他, 结合鼠标点计算出这个点的世界坐标系,然后两点一线做出射线,再判断撞击点。这个便是我们点在屏幕上的投射到场景中的位置。一口气说了这么多表示我就不去写轮子了,unityAPI中是有这样的处理的
 if( Input.GetMouseButton(0) )
        {
            Debug.Log(Input.mousePosition);
            // 获取屏幕上的点与相机的射线
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            //获取碰撞点
            if(Physics.Raycast(ray,out hit))
            {
               //debug
                Debug.Log(hit.point);
            }
            //让角色看向这个点
            transform.LookAt(hit.point);

        }

这个ScreenPointToRay方法便是获取相机与鼠标点的射线。具体效果就不截图了

				
时间: 2024-10-07 01:41:37

unity学习--003:角色控制器的相关文章

unity学习--003:角色控制器(中)

在上篇 unity学习--003:角色控制器(上)中,看了点角色控制的基本实现方法,鼠标和键盘控制比较粗糙的实现. 在这篇中,主要介绍几个unity封装的角色控制方法, 然后预计在下篇中综合介绍几种主流的角色控制方法. 话不多说,开搞: 依旧是上次拖过来的几个模型 不过,这次添加了地形,素材,和天空盒,自然光,至于怎么加的,请看这里 添加地形等 不在黑黑的,心情也好点了,下面来介绍几种unity自带的角色控制操作.(这些方法都是unity自带的API) 1.CharacterController

【Unity 3D】学习笔记三十八:角色控制器

角色控制器 在unity中,已经帮我们实现的上下左右跳等动作,并将他们封装成了角色控制器.角色控制器保存在unity标准资源包中,可以说是非常的强大.可以模拟第一或者第三人称视角.不受刚体的限制,非常适用于表现游戏中的主角运动.首先还是导入标准资源包.在project视图中点击右键,选择import package--character controller 第一人称 第一人称好比用自己的眼睛来观察游戏世界.其原理就是控制scene视图中的摄像机的移动,所以屏幕显示永远都是主角正前方的画面. 将

Unity手游之路<七>角色控制器

向原创致敬http://blog.csdn.net/janeky/article/details/17406095 我们要控制角色的移动,可以全部细节都由自己来实现.控制角色模型的移动,同时移动摄影机,改变视角.当然Unity也提供了一些组件,可以让我们做更少的工作,实现我们所期望的功能.今天我们就一起系统来学习相关的内容吧. Charactor Controller(角色控制器) "角色控制器允许你在受制于碰撞的情况下很容易的进行运动,而不用处理刚体.角色控制器不受力的影响,仅仅当你调用Mov

【Unity】11.1 角色控制器 (Character Controller)

分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 角色控制器(Character Controller)主要用于对第三人称或第一人称游戏主角的控制.如果要创建类人角色,可使用角色控制器 (Character Controller).这可以是第三人称游戏 (Third Person Platformer) 中的主角色.FPS 射击者或任何敌人角色. 二.基本概念 第三人称游戏中的这些控制器由于无规律可循,所以无法遵守固定的物理规则,例如,让某辆车每小时跑 90 英里,

【Unity】4.4 添加角色控制器

分类:Unity.C#.VS2015 创建日期:2016-04-10 一.简介 设计完毕基本的场景后,一般都需要先运行看看效果如何,即先让场景"动起来",以方便观察不同的位置,而不是仅仅观察固定摄像机位置的死板板的场景. 这就是角色控制器的功能(实际上还不仅仅是只有这些功能). Unity已经帮你设计好了角色控制器组件(Characters),你只需要导入它,然后就可以直接使用了. 二.导入Unity自带的脚色控制器 要让你设计的场景动起来,只需要导入Unity自带的Character

C#版官方角色控制器脚本

将官方自带的角色控制器脚本,改写为C#版,以下为所有代码: CharacterMotor.cs  主要设置角色控制的系数,如运动,跳跃,移动,滑动等.第一人称与第三人称主角模型的移动与旋转的角度最后都是在这里计算的. CharacterMotor.cs  代码: 1 using UnityEngine; 2 using System.Collections; 3 4 /** 5 *主要设置角色控制的系数,如运动,跳跃,移动,滑动等.第一人称与第三人称主角模型的移动与旋转的角度最后都是在这里计算的

unity学习--005:模仿几种游戏操作方式的实现

结合前面的 角色控制和镜头控制 在这里实现几种综合的操作方式 1. CF类的 第一视角控制方式 此类操控方式将摄像机绑定猪脚头部模拟第一视角 移动方式以unity自带的CharacterController.Move()方法为基础进行改进. 首先给角色判定一个Camera和下面的C#脚本 public float speed = 3.0F; public float rotateSpeed = 3.0F; void Update() { CharacterController controlle

基于Ogre的角色控制器

基本框架 首先参照这里配置好工程. 添加一个类CharacterApplication,还有main.cpp. 直接贴代码了. characterapplication.h #pragma once #include <OgreCamera.h> #include <OgreEntity.h> #include <OgreLogManager.h> #include <OgreRoot.h> #include <Ogre.h> #include

unity3d-代码控制游戏角色控制器移动

先上一个gif看看效果.因为图片大小限制.所以录制的比较小.个人认为效果比较牵强.特别是里面的逻辑代码. 不过我还是认为一切是为了先实现,因为我是刚接触的新手. 工程结构图 这次实现的效果是: 1:摄像机跟着角色移动,上篇博客说的是.把摄像机变成角色的子对象.发现没有我想要的效果.跟着角色移动代码是我自己弄出来的.不知道实际项目中是否也是这样. 2:利用角色控制器组建 CharacterController 实现角色移动. 3:当鼠左键击地形,角色自动寻路.今天发现用unity3d有自带的Nav