Unity3D游戏制作场景角色移动设备设置等.doc
《Unity3D游戏制作场景角色移动设备设置等.doc》由会员分享,可在线阅读,更多相关《Unity3D游戏制作场景角色移动设备设置等.doc(45页珍藏版)》请在冰豆网上搜索。
Unity3D游戏制作
开博写Unity的东西也写了好多,但大部分都是翻译,原创很少,接下来的一段日子,我会多写一些原创文章,介绍一些在项目中积累的简单实用的技术。
一:
3D横版场景的角色移动控制
一、导入场景,并在场景中加入TouchPlane
TouchPlane为鼠标屏幕时的Raycast平面,如下图场景中的绿线部分。
由于是横版场景,地面一般是平坦的,所以可以选择进行一个平面来作为计算鼠标投射交点。
之所以是绿线,是因为我disable该平面的MeshRender,该平面的Inspector视图如下:
值得注意的是:
1、该平面使用BoxCollider,而不用MeshCollider,这样做的好处是可以减少碰撞的计算量;
2、Tag设定为“Plane”,这是为了鼠标点击时的Raycast选取;
3、Layer设定为“TouchPlane”,这样做也是为了以后进行Raycast鼠标选取操作。
二、设定角色Component
角色Inspector视图如下图所示:
一共四个Component:
Animation、Rigidbody、CapsuleCollider以及MoveController。
Animation组件主要是角色的动作动画;
Rigidbody组件是为了角色的移动,这个我在后面会解释,这里还有一点需要注意就是不使用“UseGravity”,这样做一是因为角色只在地面上跑(如果你的游戏需要角色有跳跃功能,那么应该使用“UseGravity”,二是可以在不影响效果的同时,减少模型的物理计算);
CapsuleCollider是碰撞器,与该文章所介绍移动内容没有关系;
MoveController是自定义的角色移动控制组件,其中MoveController.cs为其对应脚本。
三、如何移动角色
流程可设定如下:
1、鼠标点击地面,通过屏幕位置来计算出其所在三维空间中角色移动的目的位置。
2、将角色从当前位置移动到鼠标点击位置
这样,我们就根据上述两个步骤来完成人物的移动操作。
(1)鼠标拾取操作
[csharp]viewplaincopyprint?
1.void Move()
2.{
3. if(Input.GetMouseButtonDown(0))
4. {
5. // m_layerMask是指TouchPlane的layer数,这也是为什么之前在设定//TouchPlane时要设定其layer的原因,这样做是为了方便鼠标拾取
6. m_layerMask = 1 << 8;
7. // 根据鼠标在屏幕空间的位置计算射线
8. m_ray = Camera.main.ScreenPointToRay(Input.mousePosition);
9. // 进行三维场景中的射线求交
10. if (Physics.Raycast(m_ ray, out m_ hitInfo, 100, m_layerMask))
11. {
12. // 如果拾取的tag为“Plane”的话
13. if (m_hitInfo.transform.tag == "Plane")
14. {
15. // 将角色朝向目标点
16. LookatTargetPos(m_ hitInfo.point);
17. }
18. }
19. }
20.}
voidMove()
{
if(Input.GetMouseButtonDown(0))
{
//m_layerMask是指TouchPlane的layer数,这也是为什么之前在设定//TouchPlane时要设定其layer的原因,这样做是为了方便鼠标拾取
m_layerMask=1<<8;
//根据鼠标在屏幕空间的位置计算射线
m_ray=Camera.main.ScreenPointToRay(Input.mousePosition);
//进行三维场景中的射线求交
if(Physics.Raycast(m_ray,outm_hitInfo,100,m_layerMask))
{
//如果拾取的tag为“Plane”的话
if(m_hitInfo.transform.tag=="Plane")
{
//将角色朝向目标点
LookatTargetPos(m_hitInfo.point);
}
}
}
}
(2)角色移动操作
[csharp]viewplaincopyprint?
1.void LookatTargetPos(Vector3 tarPos)
2.{
3. // 判断当前角色是否可以移动
4. if (!
m_bWalk)
5. return;
6. // 记录下目标点
7. m_targetPos = new Vector3(tarPos.x, tarPos.y, tarPos.z);
8. // 将角色朝向目标点
9. transform.LookAt(m_targetPos);
10. // 改变移动State
11. m_bMoving = true;
12.}
voidLookatTargetPos(Vector3tarPos)
{
//判断当前角色是否可以移动
if(!
m_bWalk)
return;
//记录下目标点
m_targetPos=newVector3(tarPos.x,tarPos.y,tarPos.z);
//将角色朝向目标点
transform.LookAt(m_targetPos);
//改变移动State
m_bMoving=true;
}
MoveController.cs中的Update函数如下:
[csharp]viewplaincopyprint?
1.void Update ()
2.{
3. Move();
4. // 如果可以移动的话
5. if (m_bMoving)
6. {
7. // 改变角色的Animation
8. animation.CrossFade("Run");
9. // 设定rigidbody的速度,由于之前已经将角色朝向目标点,所以现在的速度朝向即为transform.forward
10. rigidbody.velocity = transform.forward * 8.0f;
11.
12. // 判断角色是否该停止移动
13. if (Vector3.Distance(transform.position, m_targetPos) < 0.1f)
14. {
15. rigidbody.velocity = Vector3.zero;
16. m_bMoving = false;
17. animation.CrossFade("Idle");
18. }
19. }
20.}
voidUpdate()
{
Move();
//如果可以移动的话
if(m_bMoving)
{
//改变角色的Animation
animation.CrossFade("Run");
//设定rigidbody的速度,由于之前已经将角色朝向目标点,所以现在的速度朝向即为transform.forward
rigidbody.velocity=transform.forward*8.0f;
//判断角色是否该停止移动
if(Vector3.Distance(transform.position,m_targetPos)<0.1f)
{
rigidbody.velocity=Vector3.zero;
m_bMoving=false;
animation.CrossFade("Idle");
}
}
}
四、实现效果
通过以上设置即可控制角色在横版场景中的移动,效果图如下:
五、小结
1、该做法只适合平面的地表,如果是有起伏的,则需要使用Navmesh或其他trick来解决。
2、该做法并没有让角色与地面去做碰撞,因为本身是平面的,所以直接限定其y值,不让其使用重力作用,这样的好处可以避免不必要的物理计算。
3、角色的移动可以不用rigidbody来搞定,一般的做法还是通过Time.deltatime来一帧一帧来计算步长、移动物体,这里只是给出另外一种方法,原来其实是一样的。
二:
如何渲染3D角色
本文主要介绍一下如何利用Shader来渲染游戏中的3D角色,以及如何利用Unity提供的SurfaceShader来书写自定义Shader。
一、 从Shader开始
1、通过Assets->Create->Shader来创建一个默认的Shader,并取名“MyShader”。
2、将MyShader打开即可看见Unity默认的Shader代码
[csharp]viewplaincopyprint?
1.Shader "Custom/MyShader" {
2. Properties {
3. _MainTex ("Base (RGB)", 2D) = "white" {}
4. }
5. SubShader {
6. Tags { "RenderType"="Opaque" }
7. LOD 200
8.
9. CGPROGRAM
10. #pragma surface surf Lambert
11.
12. sampler2D _MainTex;
13.
14. struct Input {
15. float2 uv_MainTex;
16. };
17.
18. void surf (Input IN, inout SurfaceOutput o) {
19. half4 c = tex2D (_MainTex, IN.uv_Ma