古迹探险设计理念,在周围都是山的背景中在中间设置一个活动范围,将宝藏放在其中
1.在package中将人物dwarf_hero拖拽到场景中(如何进行人物大小的判断,创建一个cube可以作为参照,将人物的大小控制到1-2米即可)
2.创建一个Terrain,在设置中将地形大小面积和高度设置为20*20*20
3.绘制周围的山峰。使用笔刷绘制出周围大的山峰形成山谷效果。在属性面板中添加Light,将Intensity改为0.4,亮度变低,效果更好。
4.属性面板中选择TERRIAN中的粉刷工具。选择Texture中的add选择贴图,选择基础贴图为GrassRock图,可以选择一张图所占面积。
5.为场景添加一些石头。在package—meshes—prefabs—Rock_large,将石头围绕在场景边缘形成全包围状态。
6.为古迹添加一点内容package—meshes—prefabs中选择合适的内容添加,为使背景更加逼真
7.为场景添加一些植被草木package—meshes—Vegetation中进行选择,或者直接在属性栏中添加树。
8.给场景一些灯光效果,选择点光源,调整颜色;并且将原来就存在的平行光进行调整亮度,制造夜深的感觉。
9.石墩和火把容器的添加:package—meshes—prefabs
火把的添加:添加一个灯光,选择Light中的PointLight进行调整
10.灯光贴图:LightMapping
1)indow—Lighting—Setting可以和属性面板放在一起
2)地形和灯光属性面板中的Static勾选
3)要烘焙的话点击Generate Lighting,会自动生成光照贴图,将使用的灯光属性中的Mode属性修改为Baked,这样就仅在烘焙时起效果。当烘焙结束后,可以将属性面板中的灯光效果关闭,这样仍然会有灯光效果。一定要选中每一个灯光,而不能直接在文件夹上操作。
4)但是火把上的灯光效果需要进行Mix属性的选择,因为火把的效果需要是一个动态的效果。
5)粒子效果创建火堆效果:单击右键—Effects—Particle ystem,在属性面板中进行调整。
粒子样式的修改:在package—meshes—FX中进行样式选择
在FX中创建一个材质球,在属性面板中修改材质球的shader中的particles—additive,将fx中的图画拖拽到相应位置。再将材质球赋给例子效果,在粒子球属性面板的renderer—Material中完成。
6)但此时尚未播放动画,在粒子效果中的属性面板中选择Texture sheet Animation进行勾选,并对其Tiles进行设置。素材中是4*4的动画,所以将其数字改为4*4即可。
7)在start size中修改火苗的大小;在shape中修改形状
8)通过动画给火花添加闪烁的效果
选中要控制的灯光(要选择灯光,不要选择粒子效果进行处理)—Window—Animation,弹出对话框,选择animation进行存储的位置,并且进行命名。命名结束后,点击Add Property中的强度选项,如下图所示。
打开录制标志,经过一段时间后,在属性面板中改变强度的数值(直接在录制的状态下进行修改,自动默认关键帧,完成直接关闭,动画自动保存)
添加potision,是火苗发生左右摇曳的效果
11.导航系统—导航网络的生成
1)导航网格的烘焙:Windows—Navigation
在烘焙之前要确保环境的Static是勾选上的(至少要保证Navigation Static是勾选上的)
2)Navigation中的Bake进行烘焙,可以通过修改Agent Radius 进行调整边缘(选中右下角的Bake可以查看可行走区域)
3)如果需要任务可以穿过草丛,将草丛的Navigation Static都取消选中
4)如果不想在某个组件上生成导航网格,则需要Navigation中的Navigation Area 选择成Not Walkable模式,然后重新点击Bake进行渲染即可。
5)控制人物在导航图上进行行走:给人物添加一个Nav Mesh Agent属性组件(要保证生成的圆柱体和人物身躯大小保持一致,在radius中进行调整)
6)控制人物移动:通过鼠标单击目的地,人物自动走到目的地处。使用代码进行开发
代码中要实现的效果是获取目标位置,使用射线检测来完成。在鼠标点击的位置发射一条射线,判断和哪里发生碰撞,以获取点。
void Update () { if (Input.GetMouseButtonDown(0))//只有当鼠标点击时,需要进行检测,0表示鼠标左键 { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//获取射线。ScreenPointToRay将屏幕坐标转换成射线,通过鼠标点击进行屏幕坐标获取 RaycastHit hit;//用来保存碰撞信息 if (Physics.Raycast(ray, out hit)) //用来检测碰撞信息,传一个射线,再传一个输出 { print(hit.point);//此时点击地面Console会出现相应的坐标 } } } 此时实现的效果是:点击地面会出现相应的坐标 |
完整代码展示如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI;//正确输入命名空间
public class Hero : MonoBehaviour {
public NavMeshAgent agent;//只有这样才能正确命名这个
void Update () { if (Input.GetMouseButtonDown(0))//只有当鼠标点击时,需要进行检测,0表示鼠标左键 { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//获取射线。ScreenPointToRay将屏幕坐标转换成射线,通过鼠标点击进行屏幕坐标获取 RaycastHit hit;//用来保存碰撞信息 if (Physics.Raycast(ray, out hit)) //用来检测碰撞信息,传一个射线,再传一个输出 { print(hit.point);//此时点击地面Console会出现相应的坐标destination来对目标位置进行设置 agent.SetDestination(hit.point);//使用 } } } }
|
7)将Nav Mesh Agent 拖拽至脚本中的Agent栏,进行调节
12.控制摄像机的跟随
1)首先计算出摄像机和主角的偏移,再将Update中使相机和主角保持相同程度的偏移即可。
2)调整好摄像机的位置后,使用代码来进行控制
创建的脚本代码无法导入,直接在主相机的属性栏新建Follow Target的组件,打开其中的脚本代码进行修改即可。完整代码展示如下:
using System; using UnityEngine;
namespace UnityStandardAssets.Utility { public class FollowTarget : MonoBehaviour {
public Transform hero; private Vector3 offset;
void Start() { offset = transform.position - hero.position; }
private void LateUpdate() { transform.position = hero.position + offset; } } }
|
3)将Hierarchy中人物拖拽至Inspector相应位置,此时主摄像机可以跟随人物进行运动了
13.角色的动画控制(使用动画状态机进行控制)
1)在Animations中有四个动画,本次案例需要idle、run和walk即可。在Hierarchy中的Hero中找到Animator(属性面板中)
2)(Inspector中)Animation—Controller中进行处理。在含有动画的面板创建一个New Animator Controller,改名为hero controller如图:
3)拖拽到相应位置
如何编辑Animation—Controller?
选中需要编辑的组件(本场景中的人物)—点击Windows—选择Animator。
(1)默认状态:直接拖拽
(2)行走和奔跑,仅将动画效果进行拖拽
(3)静止、行走和奔跑状态的切换
使用人物(hero)属性面板中的Nav Mesh Agent中的speed(最大速度)进行调整。使用脚本进行切换。
(4)状态的变化需要在状态器中添加一些东西,重命名为speed
(5)将静止状态和行走状态进行连接
(6)右击如图所标注位置后出现相关属性框
(7)单击此处,生成相关内容
(8)如上图中,将Greate(最大速度)大于0时,切换速度到walk模式
(9)在walk动画上重复第(5)步,生成切换成静止模式的箭头线条,将速度的最大值改为最小值(下拉菜单),修改为小于0.1
(10)取消选择上图右侧属性界面中的Has Exit Time
(11)同理操作walk和run的动画切换。
注意:(3)步中说到的speed是最大速度,速度不能大于该数字。
(12)此时点击播放,仍然是静止状态。需要对相关参数进行赋值,在Hero代码中进行完善。
设置变量 public Animator anim; 直接在属性面板中进行拖拽 |
完整代码展示如下: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI;//正确输入命名空间
public class Hero : MonoBehaviour {
public NavMeshAgent agent;//只有这样才能正确命名这个 public Animator anim;
void Update () { if (Input.GetMouseButtonDown(0))//只有当鼠标点击时,需要进行检测,0表示鼠标左键 { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//获取射线。ScreenPointToRay将屏幕坐标转换成射线,通过鼠标点击进行屏幕坐标获取 RaycastHit hit;//用来保存碰撞信息 if (Physics.Raycast(ray, out hit)) //用来检测碰撞信息,传一个射线,再传一个输出 { print(hit.point);//此时点击地面Console会出现相应的坐标destination来对目标位置进行设置 agent.SetDestination(hit.point);//使用 } } anim.SetFloat("speed", agent.velocity.magnitude);//只需要获取速度的大小 } }
|