Unity3D入门基础知识汇总
1. unity界面
右上边可以切换布局。
左边选择Shaded wireframe,可以看到3D物体的都是由三角形组成的。
2. 物体显示
网格(三角形构成)+ 材质
3. 资源商店
Windows -> Asset Store
挑出喜欢的资源之后,点击”添加至我的资源”。
然后在Unity的Window -> Package Manager中找到刚才的资源。
点击下载之后再导入到untiy中
4. 组件
在Unity中,功能基本上都是由组件来实现的。如果想要一个物体移动,那么为它添加一个有移动功能的组件就可以了。
每个游戏的物体都是一个空物体,它之所以表现为不同的形式,都是由它的组件表现出来的。由于组件(cube组件、light组件)不同,所以表现出来的形态也不同。
(1)添加系统提供的组件
选择物体后,通过右下角的“Add Component”功能,选择Rigidbody组件,然后选择执行,那么该物体就会垂直下落。
(2)自定义组件
创建C#脚本,然后放到物体下面就可以了。
5. 脚本的生命周期
创建一个脚本之后,会看到默认的两个方法Start()和Update()方法。
全部的生命周期方法为:
Awake:最早调用,一般可以在此实现单例模式
OnEnable:组件激活后调用,在Awake后会调用一次
Start:在Update之前调用一次,在OnEnable之后调用,可以在此设置一些初始值
FixedUpdate:固定频率调用方法,每次调用与上次调用的时间间隔相同
Update:帧率调用方法,每帧调用一次,每次调用与上次调用的时间间隔不相同
LateUpdate:在Update每调用完一次后,紧跟着调用一次。
OnDisable:与OnEnable相反,组件未激活时调用
OnDestory:被销毁后调用一次
在方法中打印日志使用Debug.Log(“”);
然后在Window -> General -> Console 看到日志输出
6. 脚本的执行顺序
如果针对一个物体创建了两个脚本,在默认情况下脚本的执行顺序是不定的。
有两种方法可以指定方法的执行顺序。
方法一:
在每个脚本不同的生命周期函数中编写功能,比如脚本1的Awake函数中执行功能1,脚本2的Start函数中执行功能2,这样可以保证先执行功能1,再执行功能2。
所有的脚本都是按照生命周期,先执行完所有的Awake函数,再执行所有的OnEnable函数,依此类推。
方法二:
直接指定各个脚本的优先级。
7. 标签和图层
标签的作用:一般是自己用的,可以用来区分每个的角色,比如是敌人还是玩家。
图层的作用:一类内容,通过图层可以判断哪一类显示,哪一类不显示。比如某个图层的物体需要检测碰撞,而另一个图层的内容( 比如地面)不需要检测碰撞。
8. 向量的概念
标量:只有大小的量,1 85 888 999
向量:既有大小,也有方向
向量的模:向量的大小
单位向量:大小为1 的向量
单位化、归一化:把向量转为单位向量的过程。
向量的点乘:A向量 点乘 B向量 = 数值n = |A||B|cos&,得到两个向量之间的夹角。
9. 预制体与变体
现在做了如下的物体(总共由4个部分组成),
假如现在需要4个这种物体,
如果在SampleScene界面直接再复制3个出来,那么假如这个物体需要改动,那么需要改动4个物体,怎么才能只修改一个物体,其他的同步生效?
这就需要用到预制体。
把物体从SampleScene复制到Assets中,然后再复制3个Enemy到SampleScene中,如下图所示
此时如果修改Assets中的Enemy,则直接双击进行修改,修改完成后所有的都会生效
所有都生效如下图所示:
现在有新的任务:需要新增一个物体,新物体比之前4个物体只增加一顶帽子,其他的部分需要与之前4个保持一致。即除了帽子外,4个物体做了改动,当前新物体也需要同步做改动。此时需要用到变体的功能。
当在SampleScene中创建了新物体,然后拖动到Assets时提示如下,选择Prefab Variant(预制体变体)。
此时在Assets的Enemy中做修改,5个会同时生效,比如把红色嘴巴变小了之后
此时,预制体修改会影响变体,但是变体修改不会影响预制体。
10. 脚本中vector3的作用
第一,Vector3可以表示:
1)向量(坐标)
Vector3 v = new Vector3(1, 1, 1);
2)旋转
Vector3 v = new Vector3(45, 90, 0);
3)缩放
Vector3 v = new Vector3(1, 1, 0.5f);
第二,系统提供的静态初始化方法
v = Vector3.zero;
第三,计算两个向量之间的关系
// 向量,坐标,旋转,缩放Vector3 v = new Vector3(1, 1, 0.5f);v = Vector3.left;Vector3 v2 = Vector3.forward;// 计算两个向量的夹角Debug.Log(Vector3.Angle(v, v2));// 计算两个向量的举例Debug.Log(Vector3.Distance(v, v2));// 点乘Debug.Log(Vector3.Dot(v, v2));
得到的结果:
- 方向的描述,欧拉角与四元数
欧拉角:从0到360度
四元数:比欧拉角要强大很多,效率更高,也不会造成万向节死锁
代码示例:
// 欧拉角Vector3 rotate = new Vector3(0, 30, 0);// 四元数Quaternion quaternion = Quaternion.identity; // 创建了一个四元数,但是无旋转quaternion = Quaternion.Euler(rotate); // 通过欧拉角创建四元数// 看向一个物体quaternion = Quaternion.LookRotation(new Vector3(0, 0, 0)); // 看向一个物体肯定要做旋转// 四元数转欧拉角rotate = quaternion.eulerAngles
12. Unity3D中的调试
(1)打印日志的方式
Debug.Log("test1");Debug.LogWarning("test2");Debug.LogError("test3");
(2)绘制线条的方式
// 绘制一条线(起点,终点)Debug.DrawLine(Vector3.zero, Vector3.one, Color.blue);// 绘制一条射线(起点,射线)Debug.DrawRay(Vector3.zero, Vector3.up, Color.red);
13. 游戏物体的使用
一个游戏物体,上面包含很多组件,每个组件不同的功能,这样一个物体就有不同的功能。每一个游戏物体都是GameObject类。
(1)拿到当前脚本所挂载的游戏物体
GameObject go = this.gameObject;
Debug.Log(go.name);
(2)在当前脚本中操作子物体(另一个物体)
首先,是在脚本中定义一个子物体。
然后,当前物体就增加了一个属性
接着,在SamplesScene中创建子物体Cube,并拖到Script的Cube中,即实现了物体和属性的关联,此时脚本中的Cube有值了。
(3)获取游戏物体并进行操作
// 获取Transform组件
Debug.Log(transform.position);// 获取其他组件
BoxCollider bc = GetComponent<BoxCollider>();// 添加一个组件
Cube.AddComponent<AudioSource>();// 通过游戏物体的名称来获取游戏物体
GameObject test = GameObject.Find("Test");
Debug.Log(test.name);// 通过游戏标签获取游戏物体
test = GameObject.FindWithTag("Enemy");Debug.Log(test.name);
test.SetActive(false); // 设置激活状态
(4)创建物体
通过预设体(类)创建物体(实例)。
首先,声明一个物体
然后,把一个预设体关联上该变量,操作同《在当前脚本中操作子物体(另一个物体)》
接着,脚本中创建物体
Instantiate(Prefab);
或者实例化一个物体并指定位置信息:Instantiate(Prefab, Vector3.zero, Quaternion.identity);
(5)销毁物体
// 通过预设体来实例化一个游戏物体GameObject go = Instantiate(Prefab, Vector3.zero, Quaternion.identity);// 销毁Destroy(go);
- 时间的使用方法
时间统计方法
// 游戏开始到现在所花的时间
Debug.Log(Time.time);// 时间缩放值
Debug.Log(Time.timeScale);// 固定时间间隔
Debug.Log(Time.fixedDeltaTime);// 上一帧到这一帧所用的游戏时间
Debug.Log(Time.deltaTime);
- Application类
1)常用的路径信息
// 游戏数据文件夹路径(当前Assets所处的路径,只读且加密压缩)
Debug.Log(Application.dataPath);
比如:D:/workspace/unity/FirstProject/Assets
// 持久化文件夹路径(系统给应用程序分配的存放数据的空间,可写)
Debug.Log(Application.persistentDataPath);
比如:C:/Users/hugh/AppData/LocalLow/DefaultCompany/FirstProject
// StreamingAssets文件夹路径(只读不压缩,可放配置文件等不需要压缩的文件)
Debug.Log(Application.streamingAssetsPath);
比如:D:/workspace/unity/FirstProject/Assets/StreamingAssets
// 临时文件夹
Debug.Log(Application.temporaryCachePath);
比如:C:/Users/hugh/AppData/Local/Temp/DefaultCompany/FirstProject
(2)控制类接口
// 控制是否在后台运行
Debug.Log(Application.runInBackground);// 打开url
Application.OpenURL("http://www.baidu.com");// 退出游戏
Application.Quit();
16. 场景
(1)游戏-场景-物体-组件的关系
2)项目中默认的一个场景SampleScene
(3)创建新的场景MyScene
Scenes目录右击 -> Create -> Scene
(4)场景间的跳转
从SampleScene场景跳转到MyScene场景。
第1步,生成场景的索引号
File -> Build Settings
拖动场景到”Scenes In Build”中。
此时就生成了场景的索引号信息。
第2步,在脚本中实现跳转
场景涉及到Scene、SceneManager两个类。
同一时间可以存在多个场景,场景是可以叠加在一起的。
示例代码如下:
//场景跳转
//SceneManager.LoadScene(0); // 通过索引方式跳转
//SceneManager.LoadScene("MyScene"); // 通过名称方式跳转// 获取当前场景
Scene scene = SceneManager.GetActiveScene();// 场景名称
Debug.Log(scene.name);// 场景是否已经加载
Debug.Log(scene.isLoaded);// 场景路径
Debug.Log(scene.path);// 场景索引
Debug.Log(scene.buildIndex);GameObject[] gos = scene.GetRootGameObjects();
Debug.Log(gos.Length);// 场景管理类
// 创建新场景
Scene newScene = SceneManager.CreateScene("newScene");
Debug.Log(SceneManager.sceneCount); // 当前激活的场景个数// 卸载场景
SceneManager.UnloadSceneAsync(newScene);// 加载场景的两种方式
//SceneManager.LoadScene("MyScene", LoadSceneMode.Single); // 替换方式的加载
SceneManager.LoadScene("MyScene", LoadSceneMode.Additive); // 叠加方式的加载
17. 异步加载场景并获取进度
打印的日志:(测试场景资源太少,所以立马就加载完毕了,显示0.9)
18. Transform的作用
它有两个作用:
1)控制物体的位置、旋转、缩放
2)控制父子级的从属关系
演示Transform的使用
首先,创建父子孙物体Parent\Sphere\Child,并将脚本TransformTest挂在Sphere物体上。
(1)获取位置等属性信息
// 获取位置Debug.Log(transform.position); // 世界坐标Debug.Log(transform.localPosition); // 相对父级的位置// 获取旋转Debug.Log(transform.rotation);Debug.Log(transform.localRotation);Debug.Log(transform.eulerAngles);Debug.Log(transform.localEulerAngles);// 获取缩放
Debug.Log(transform.localScale);// 向量
Debug.Log(transform.forward);
Debug.Log(transform.right);
Debug.Log(transform.up);
(2)物体运动操作
// 时时刻刻看向000点transform.LookAt(Vector3.zero);// 旋转(自转)transform.Rotate(Vector3.up, 1);// 旋转(公转)transform.RotateAround(Vector3.zero, Vector3.up, 1);// 移动transform.Translate(Vector3.forward * 0.1f);
(3)父子关系
// 获取父物体GameObject go = transform.parent.gameObject;// 子物体个数Debug.Log(transform.childCount);// 解除与子物体的父子关系transform.DetachChildren();// 获取子物体Transform trans = transform.Find("Child"); // 根据名称获取trans = trans.GetChild(0); // 根据索引获取// 判断一个物体是不是另外一个物体的子物体bool res = trans.IsChildOf(transform);// 设置为父物体trans.SetParent(transform);
19. 监听键盘和鼠标
对于这两个设备的监听,需要每一帧都监听,所以逻辑要写在Update()方法中。
// 鼠标的点击
// 按下鼠标 0左键 1右键 2滚轮
if (Input.GetMouseButtonDown(0))
{Debug.Log("按下了鼠标左键");
}
// 持续按下鼠标
if (Input.GetMouseButton(0))
{Debug.Log("持续按下鼠标左键");
}
// 抬起鼠标
if (Input.GetMouseButtonUp(0))
{Debug.Log("抬起了鼠标左键");
}// 按下键盘按钮
if (Input.GetKeyDown(KeyCode.A))
{Debug.Log("按下了A");
}
if (Input.GetKey(KeyCode.A))
{Debug.Log("持续按下了A");
}
if (Input.GetKeyUp(KeyCode.A))
{Debug.Log("松开了A");
}
20. 虚拟轴
适配各个平台,通过虚拟轴来控制上下左右、跳跃等操作。否则电脑上使用WSAD控制上下左右,而在游戏手柄中使用摇杆。
(1)查看虚拟轴
打开Edit -> Project Settings
在Input Manager中,只有Horizontal和Vertical是虚拟轴(有多个值),其他的是虚拟按钮。
(2)使用虚拟轴和虚拟按键
// 获取水平/垂直轴
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Debug.Log(horizontal + " " + vertical);// 虚拟按键
if (Input.GetButtonDown("Jump")) {Debug.Log("空格");
}
21. 摸方法使用
22. 灯光
创建灯光:Light -> Point Light
四种光源类型:
方向光:Directional Light 用于模拟太阳光,方向光任何地方都能照射到
点光源:Point Light 用于模拟电灯泡的照射效果
聚光灯:Spot Light 用于模拟聚光灯照射效果
区域光:Area Light 区域光在“实时光照”模式下是无效的,只用于“烘培光照”模式。
(1)方向光
此时移动光源,阴影的角度不会发生改变
当旋转光源时,阴影的方向是会变化的。
(2)点光源
随着光源的移动,照射的位置会发生变化
(3)聚光灯
类似摄影棚的聚光灯效果
硬阴影:阴影有锯齿状,系统性能开销较低
软阴影:边缘有羽化模糊效果,系统性能开销大一些
(5)实时/烘培灯光
实时:实时计算出来的,比如赛车时车灯照射到的地方,非常耗性能
烘培:提前保存灯光照射数据,然后把灯光去掉,灯光效果仍然保留
23. 灯泡、摄像头图标不见了怎么办
点击如下按钮:
该按钮的意思:toggle visibility of all Gizmos in the Scene view
即:在“场景”视图中切换所有Gizmo的可见性
24. 摄像机
两种摄像机类型:透视摄像机、正交摄像机
(1)透视摄像机
该摄像机有着近大远小的特点,与我们现实中看到的相同。
(2)正交摄像机
没有近大远小的效果,当两个同样大小的物体到摄像机的距离不同时,其显示出的大小仍然是相同的。
透视和正交的选项如下:
3D的一般是透视,2D的一般是正交。多个摄像机可以融合在一起,深度的处理。
25. 音乐和音效
音乐:比较长的背景音乐,在场景中往往是循环播放
音效:比较短的声音,比如射击的声音
一个场景中只能同时存在一个音乐,但是可以同时存在很多的音效。
(1)听声音
如果希望游戏中可以听到声音,必须要有一个组件在场景中存在,即”Audio Listener”,该组件用于接收声音。位于摄像机的物体中,同时该组件在一个场景中只能存在一次。
(2)播放声音
方法一:直接在Inspector中进行配置
选中一个物体,然后添加“Audio Source”的组件。
AudioClip:音频剪辑,所有的声音都属于音频剪辑。
方法二:在脚本中控制播放
代码如下:
public class AudioTest : MonoBehaviour
{// Start is called before the first frame update// AudioClippublic AudioClip music;public AudioClip se;// 播放器组件private AudioSource player;void Start(){player = GetComponent<AudioSource>();// 设定播放的音频片段player.clip = music;// 循环player.loop = true;// 音量player.volume = 0.5f;// 播放player.Play();}// Update is called once per framevoid Update(){// 按空格切换声音的播放和暂停if (Input.GetKeyDown(KeyCode.Space)) {// 如果当前正在播放声音if (player.isPlaying){// 暂停播放player.Pause();}else {player.UnPause();}}// 按鼠标左键播放声音if (Input.GetMouseButtonDown(0)){player.PlayOneShot(se);}}
}
26. 视频播放
第一步,创建渲染器纹理(Assets -> Create -> Render Texture)
第二步,创建平面,后面我们希望在平面上显示视频(SampleScene -> 3D Object -> Plane)
第三步,在平面上增加组件“Video Player”,执行Video Clip为我们准备的视频文件,然后在Render Mode中选择Render Texture,然后把第一步创建的纹理拖过来。
第四步,把纹理应用到平面上,拖过去即可。
最后,点击运行即可。
27. 角色控制器
角色控制的三种解决方案:
- 应用商品中有很多成熟的解决方案
- 要求不高的话,使用unity3d提供的角色控制器
- 通过物理系统进行角色控制
本次使用第二种即角色控制器。
首先,创建画板和胶囊
然后,添加角色控制组件,Character Controller。
接着,创建脚本。
public class PlayerController : MonoBehaviour
{// Start is called before the first frame updateprivate CharacterController player;void Start(){player = GetComponent<CharacterController>();}// Update is called once per framevoid Update(){// 水平轴float horizontal = Input.GetAxis("Horizontal");// 垂直轴float vertical = Input.GetAxis("Vertical");// 创建成一个方向向量Vector3 dir = new Vector3(horizontal, 0, vertical);// 朝向该方向移动player.SimpleMove(dir * 2);}
}
28. 物理系统做游戏碰撞
在物体的Mesh Collider中进行设置。
在组件中存在很多的碰撞器,比如Mesh Collider(网格碰撞器)、Terrain Collider(地形碰撞器)等。
两个物体如果要碰撞的前提条件:
1)两个物体都有碰撞器。
2)至少一个物体有RigidBody(刚体),即受重力影响
碰撞示例:
29. 触发
触发的条件同碰撞一样,即都有碰撞器、至少一个有刚体。
触发和碰撞的区别:
- 触发时,有一个的碰撞器的“Is Trigger”设置为true
- 程序运行时,当物体为触发器属性时,可以被另一个物体穿透,而非触发器属性则不能。如下图所示:
示例:
一个胶囊物体+2个触发器的Cube。
胶囊物体(模拟玩家)的代码如下:
左下角隐藏物体的代码:
private void OnTriggerEnter(Collider other){GameObject wall = GameObject.Find("Wall");if (wall != null){wall.SetActive(false);}}
30. 铰链、弹簧
它们都属于物理关节。
铰链:类似于门的关节,通过这个关节实现门的旋转
弹簧:将两个物体连接在一起,两个的运动有弹簧的效果。
铰链的示例:
蓝色的Cube设置铰链的效果。
首先,设置rigidBody刚体属性。
然后,增加Hinge Joint铰链,设置Anchor和Axis属性,分别控制铰链的位置和方向。
31. 用鼠标控制移动,射线检测
在平面上,鼠标按一个位置(鼠标无法在3d上指定一个具体位置),物体就会移动到这个位置上,这个怎么实现的?
点击一个位置后,从摄像机发射一个射线到指定的方向,该射线与平面接触后即得到了具体位置,然后就可以让物体移动到该位置。
代码示例:
void Update(){if (Input.GetMouseButtonDown(0)){// 按下鼠标左键发射射线Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);// 声明一个碰撞信息类RaycastHit hitInfo;// 碰撞检测bool res = Physics.Raycast(ray, out hitInfo);// 如果碰撞到的情况下,hitInfo就有内容了if (res){transform.position = hitInfo.point; }}
32. 粒子系统
特效相关的功能
使用:右击 -> Effects -> Particle System
33. 动画
动画有老版(Animation)和新版(Animator)两个组件。
(1)Animation组件
目前动画组件中缺失动画。
制作动画(一个cube左右移动的动画):Window -> Animation -> Animation打开制作面板。
首先,创建动画剪辑。
然后,添加属性(比如Transform的Position)
点击播放可以进行预览。
然后将该动画放到Animation组件的Animation Clip中。
(2)Animator组件
使用示例:
首先,创建Animator组件,该组件需要输入Animator Controller信息。
然后,在Assets中Create -> Animator Controller,该控制器如下图所示,同时将该控制器拖入Animator组件的Controller选项中。
接着,创建Animation。选中物体后Window -> Animation,创建right
接着,继续创建动画脚本left。
接着,再点击Animator的Controller选项中的Animator Controller,会出现如下画面。
Right高亮,这表明程序进入后直接执行right动画。
最终,通过代码演示点击鼠标后切换为left动画。
public class AnimatorTest : MonoBehaviour
{private Animator animator;// Start is called before the first frame updatevoid Start(){animator = GetComponent<Animator>();}// Update is called once per framevoid Update(){if (Input.GetMouseButtonDown(0)) {animator.Play("left");}}
}
34. 让角色动起来
首先,下载资源Character Pack: Free Sample
然后,创建Plane,然后把上一步的角色放进去。角色位于:Prefabs -> High Quality -> MaleFree1.
接着,创建动画控制器,并将该控制器拖到角色的Animator的Controller里面。
双击Controller之后,将FBX的动画文件拖到Animator中即可执行。
如果想要一个角色执行两个动作,就拖入两个动画脚本,然后通过“Make Transition”关联起来。如下所示:
此时,角色会循环执行第1、2个动作。如何实现通过按键在第1、2个动作之间进行过度?此时需要在第1、2个动作之间增加条件。
在Animator面板的Parameters-> “+” -> Trigger,
- 点击idle和pickup之间的transition
- 增加一个trigger为pickup
- 在检查器面板的conditions中增加pickup
- 去掉Has exist time(使idle到pickup的触发能立即生效)
此时点击左上角的pickup就会立马触发第2个动作。
怎么在代码中实现触发?
补充说明:Trigger只是触发一下,没有持续性。
35. 使用按键控制角色运动
(1)让角色在静止和运动之间切换
参数类型选择bool,会永久性进行切换
(2)过度Transition的设置
(3)实现运动的代码
public class PlayerController4 : MonoBehaviour
{// Start is called before the first frame updateprivate Animator animator;void Start(){animator = GetComponent<Animator>();}// Update is called once per framevoid Update(){// 水平轴float horizontal = Input.GetAxis("Horizontal");// 垂直轴float vertical = Input.GetAxis("Vertical");// 向量Vector3 dir = new Vector3(horizontal, 0, vertical);// 当用户按下方向键if(dir != Vector3.zero){// 面向向量transform.rotation = Quaternion.LookRotation(dir);// 播放跑步动画animator.SetBool("isRun", true);// 朝向前方移动transform.Translate(Vector3.forward * 2 * Time.deltaTime);}else{animator.SetBool("isRun", false);}}
}
- 动画FBX属性说明
Model:模型相关的信息
Rig:动画类型:无(当前文件不包含动画),旧版(只能使用Animation组件),其他的泛型和人形都是Animator才有的。泛型支持所有类型。人形:官网提供的各种人形动画,可以套在人形的物体中,这样对于人形比较通用。
Animation:动画,可以生成新的动画剪辑。
Curves:曲线,该曲线对动画不产生影响,该曲线是为了外部能感受到动画的细节以便做出相应的指令。比如,角色挥拳产生火焰,可以根据曲线决定火焰的大小。
Events:事件。当运动到某一动作时指定一个触发事件(回调函数)。
然后在脚本中编写leftFoot的功能。
void leftFoot()
{Debug.Log("左脚!");
}
37. 制作混合动画
在Animator面板的Base Layer中右击 -> Create State -> From New Blend Tree
双击Blend Tree可以进入子目录。
在右侧的List中增加2个motion如下:
通过blend的值控制融合的权重。
38. 动画的图层
默认情况下是一个Base的图层,如下所示:
它有3个状态,
- Entry:入口的指定状态
- Any State:任一状态,假如场景中有100个动画,如果Any State和run相连,则100个动画都可以过度到run
- Exit:结束状态
还可以创建子状态集如下:
子状态集进去后如下:
后续可以针对一个人物创建多个子状态集,比如拿刀的是一个子状态,拿枪的是一个子状态,然后人物可以在状态之间相互切换。
39. 反向动力学
功能:我们希望这个人物走到哪里,都可以看向这个球,并且手也指向这个球。
何为反向动力学:
在正向动力学中,一个人抬起手的顺序是1、2、3,即先抬起胳膊、然后抬起手臂、再抬起手。而反向动力学是反过来,即3、2、1。
IK动画:脚本控制模型骨骼动画。
代码示例(在第40节中增加如下代码):
public Transform target; // 人物指向的物体// IK写到这个方法内
private void OnAnimatorIK(int layerIndex)
{// 设置头部IKanimator.SetLookAtWeight(1);animator.SetLookAtPosition(target.position);// 设置右手IK权重animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1); // 除了头部其他都采用枚举值// 设置右手IK权重// 旋转(举起手旋转)animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);// 设置右手IKanimator.SetIKPosition(AvatarIKGoal.RightHand, target.position);animator.SetIKRotation(AvatarIKGoal.RightHand, target.rotation);
}
效果如下:
40. 导航网格
导航组件是用来智能寻路的。
(1)导航系统可走的区域
哪些区域可以走,哪些区域不可以走,是对当前的场景生成网格来实现的,网格内的可以走,网格外的不可以走。
首先,选中需要制作网格的物体后,点击Navigation->Object,Navigation Static打勾。
然后,点击Base选项,设置参数完毕后,点击最下面的bake
就生成了网格区域。
Agent Radius:代理半径,就是模拟人的宽度
Agent Height:代理高度,就是模拟人的高度
Max Slope:允许行走的倾斜度
Step Height:允许人走的每一步的高度
(2)让物体在网格区域行走
首先,给胶囊(模拟人)添加导航代理组件。
Agent Type选择”Open Agent Settings”可以设置多个代理,比如人有高有矮,就可以设置不同参数的代理。
然后,通过脚本控制胶囊移动
(3)动态障碍物
当前场景上下两部分被中间的墙隔断了。
有时我们希望一个城墙移动后,两边就打通了,做成动态障碍物,而不是现在的静态障碍物。
做法:
第1步,把Door的navigation static反勾选
第2步,给Door添加组件Nav Mesh Obstacle,在该组件中勾选Carve,此时就会进行动态切割,也就是动态烘焙。
此时,把中间的door打开,物体就可以两边自由行走。而把door关闭,就只能单边行走了。
(4)网格链接
任务一:从一个区域直接跳到另一个区域,比如直接从台上跳到地面上。
首先,选择需要跳的台面,点击该台面的Navigation,勾选Generate OffMeshLinks,就创建了网络链接。
然后,选择胶囊,点击Navigation,在Generated Off Mesh Links,填写Drop Height的值(允许跳落得高度),就会在Scene上看到可挑落点。
任务二:从一个地方跳到另一个指定得位置
比如,从白点1的位置,希望可以瞬间转移到白点2的位置。
做法:
- 创建两个cube
- 随机选择一个cube,添加组件Off Mesh Link
- 然后把两个物体分别拖入Off Mesh Link组件的Start和End的位置
- UI画布
首先,准备素材
搜索资源“Fantasy Free GUI”
然后,创建画布
创建完毕后如下图所示:
当创建完画布Canvas后,系统检测到没有事件系统,会自动创建EventSystem。后续在画布上增加按钮,就可以响应按钮的点击事件了。
画布在3D世界中就是如上图的白色线框,默认线框的比例和下方游戏窗口的比例是一致的。
Canvas组件的RenderMode参数:
右击Canvas,选择UI -> Image,然后在Source Image中选择一张图片
1)Screen Space-Overlay 屏幕空间-覆盖模式
覆盖模式跟摄像机无关,画布上的图像优先级最高,总能出现在屏幕的最前方,覆盖所有其他的物体。
2)Screen Space-Camera 屏幕空间-摄像机
就是根据摄像机拍摄的角度,显示内容。需要在Render Camera中拖入一个摄像机,如下图所示,可以看到cube挡住了画布上的图像。
3)World Space 世界空间
与Camera相似,但是可以旋转画布,此时就可以操作Rect Transform的参数。
Canvas Scaler组件的UI Scale Mode参数
- Constant Pixel Size:固定的像素大小,按照屏幕的大小进行显示
- Scale With Screen Size:屏幕大小缩放(比较多人使用的方式)
此时无论游戏屏幕怎么变化,最终游戏都会根据1920*1080进行适配显示。
42. UI的图片的锚点、轴心点
下图中左边红框的为画布的瞄点,而图片的PointX、PointY的坐标即为图片的轴心相对瞄点的坐标。
假如将画布的瞄点拆分为矩形的四个顶点,那么随着设备的分辨率变化,图片会进行相应的伸缩。否则图片大小固定,在不同分辨率下的设备呈现不同的显示。
43. UI按钮
有两个地方可创建文本和按钮。
旧版UI->Legacy,两者的区别是组件不同。
更改按钮的图标:
Button设置中的Transition可以设置为Sprite Swap(精灵类型,可包含图片)。
按钮触发事件:可把脚本挂在到Canvas上。
然后点击Button,选择对象上的函数进行关联。此时选择Canvas对象的对应的ButtonTest的ButtonClick1函数,其他几个button可依次这样进行操作。
44. UI输入框
位于UI -> Legacy -> Input Field
输入框有3个事件,使用方法和Button的事件相似。
新旧版输入框脚本上的差异:
45. UI之选项
位于UI -> Toggle
怎么保证只能2选1呢?
选择Canvas后,添加组件Toggle Group
然后分别选择Toggle1和Toggle2,Group参数选择刚才Canvas中创建的组件
46. UI之下拉列表
位于:UI -> Legacy -> Dropdown
动态添加选项的方法:
47. UI之面板Panel
在界面中我们作图,完成后如下图所示:
在不同的分辨率下会呈现不同的结果,如下图所示:
此时需要通过Panel来固定位置:
选择UI -> Panel,然后选择左上角对齐锚点,反选Image。
此时改变显示屏的分辨率,显示的图像位置都不会发生变化。
相关文章:
Unity3D入门基础知识汇总
1. unity界面 右上边可以切换布局。 左边选择Shaded wireframe,可以看到3D物体的都是由三角形组成的。 2. 物体显示 网格(三角形构成) 材质 3. 资源商店 Windows -> Asset Store 挑出喜欢的资源之后,点击”添加至我的…...
Triton学习笔记
b站链接:合集Triton 从入门到精通 文章目录 算法名词解释:scheduler 任务调度器model instance、inference和requestbatching 一、Triton Inference Server原理1. Overview of Trition2. Design Basics of Trition3. Auxiliary Features of Trition4. A…...
办理公司诉讼记录删除行政处罚记录删除
企业行政处罚记录是可以做到撤销消除的,一直被大多数企业忽略,如果相关诉讼记录得不到及时删除,不仅影响企业招投标,还影响企业的贷款申请,严重的让企业资金链断裂,影响企业长远发展和企业形象。行政处罚是…...
IO流字符流(FileReader与FileWriter)
目录 FileReader 空参read方法 带参read方法👇 FileWriter void write(intc) 写出一个字符 void write(string str) 写出一个字符串 void write(string str,int off,int len) 写出一个字符串的一部分 void write(char[] cbuf) …...
使用 GPT-4 创作高考作文 2024年
使用 GPT-4 创作高考作文 2024年 使用 GPT-4 创作高考作文:技术博客指南 🤔✨摘要引言正文内容(详细介绍) 📚💡什么是 GPT-4?高考作文题目分析 ✍️🧐新课标I卷 人类智慧的进步&…...
计算机网络 期末复习(谢希仁版本)第5章
**屏蔽作用:**运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道。 10. 端口用一个 16 位端口号进行标志,允许…...
CSAPP Lab01——Data Lab完成思路
陪你把想念的酸拥抱成温暖 陪你把彷徨写出情节来 未来多漫长再漫长还有期待 陪伴你 一直到 故事给说完 ——陪你度过漫长岁月 完整代码见:CSAPP/datalab-handout at main SnowLegend-star/CSAPP (github.com) 01 bitXor 这道题是用~和&计算x^y。 异或是两个…...
将小爱音箱接入 ChatGPT 和豆包,改造成你的专属语音助手
网址 https://github.com/idootop/mi-gpt 一个ts的项目,看样子是个纯前端的项目。 演示的挺有意思的,傻妞应该是魔幻手机的角色。感觉能用这个例子的,最少得三十而立了。 个人感觉这种项目都是整活加炫技,估计我要用上这东西&…...
mongodb总概
一、mongodb概述 mongodb是最流行的nosql数据库,由C语言编写。其功能非常丰富,包括: 面向集合文档的存储:适合存储Bson(json的扩展)形式的数据;格式自由,数据格式不固定,生产环境下修改结构都可以不影响程序运行;强大的查询语句…...
【设计模式】策略模式(行为型)⭐⭐
文章目录 1.概念1.1 什么是策略模式1.2 优点与缺点 2.实现方式3. Java 哪些地方用到了策略模式4. Spring 哪些地方用到了策略模式 1.概念 1.1 什么是策略模式 它允许用户在不修改现有对象的代码的情况下向对象添加新的功能;这种模式是通过创建一个包含该对象的包装…...
《软件定义安全》之三:用软件定义的理念做安全
第3章 用软件定义的理念做安全 1.不进则退,传统安全回到“石器时代” 1.1 企业业务和IT基础设施的变化 随着企业办公环境变得便利,以及对降低成本的天然需求,企业始终追求IT集成设施的性价比、灵活性、稳定性和开放性。而云计算、移动办公…...
pdf文件在线压缩网站,pdf文件在线压缩工具软件
在数字化时代的今天,PDF文件已经成为我们日常生活和工作中不可或缺的一部分。然而,随着PDF文件的广泛使用,其文件大小问题也日益凸显。过大的PDF文件不仅占用了大量的存储空间,而且在传输和共享过程中也往往面临诸多不便。因此&am…...
java程序100道21-30
21.定义一个接口A,有一个String的常量值为Java的 s,有void 的print()方法和String 的getInfo()方法,类X是A的实现类,类A的print()方法输出常量s,方法getInfo()返回“Hello!!!” package Exercises.One_Hundred.Demo21; public…...
英伟达SSD视觉算法模型训练、转换与部署
深度学习的训练和推理流程,是先采用高性能图形服务器使用深度学习框架来训练(Training)机器学习算法,研究大量的数据来学习一个特定的场景,完成后得到模型参数,再部署到终端执行机器学习推理(Inference),以训练好的模型从新数据中得出结论。 一般的深度学习项目,训练…...
智能变电站网络报文记录及故障录波分析装置
是基于Intel X86、PowerPC、FPGA等技术的高度集成化的硬件平台,采用了高性能CPU无风扇散热、网络数据采集、高速数据压缩存储加密等多种技术,实现了高性能计算、多端口同步高速数据采集、数据实时分析、大容量数据存储等功能。 ● 在满足工业标准的同时&…...
npm ERR! code E404 npm ERR! 404 Not Found - GET https://registry.npmjs.org/
npm ERR! code E404 npm ERR! 404 Not Found - GET https://registry.npmjs.org/ 📜 智能合约依赖下载失败的解决方案摘要引言正文内容1. 场景描述 🤔2. 可能原因分析2.1 包不存在或名称错误2.2 网络问题2.3 npm配置错误 3. 解决方案🛠️3.1 …...
Dockerfille解析
用于构建Docker镜像的文本,由一条条指令构成 Docker执行Dockerfile的流程 1. Docker从基础镜像执行一个容器 2. 执行一条指令并对容器进行修改 3. 执行类型Docker commit的命令添加一个新的镜像层 4. Docker再基于新的镜像执行一个新的容器 5. 执行Dockerfile中…...
定个小目标之刷LeetCode热题(14)
了解股票的都知道,只需要选择股票最低价格那天购入,在股票价格与最低价差值最大时卖出即可获取最大收益,总之本题只需要维护两个变量即可,minPrice和maxProfit,收益 prices[i] - minPrice,直接用代码描述如下 class …...
智慧管道管理:油气管道可视化的领先应用
通过图扑油气管道可视化技术,实现实时监控与数据分析,快速识别潜在风险,有效提升管道维护效率和安全性能。...
嵌入式仪器模块:示波器模块和自动化测试软件
示波器模块 • 32 位分辨率 • 125 MSPS 采样率 • 支持单通道/双通道模块选择 • 低速模式可实现实时功率分布和整机功率检测 • 高速模式可实现信号分析和上电时序测量 应用场景 • 抓取并分析波形的周期、幅值、异常信号等指标 • 电源纹波与噪声分析 • 信号模板比…...
组装服务器重装linux系统【idrac集成戴尔远程控制卡】
🍁博主简介: 🏅云计算领域优质创作者 🏅2022年CSDN新星计划python赛道第一名 🏅2022年CSDN原力计划优质作者 🏅阿里云ACE认证高级工程师 🏅阿里云开发者社区专…...
景区ar互动大屏游戏化体验提升营销力度
从20世纪60年代的初步构想,到如今全球范围内无数企业的竞相投入,AR增强现实技术已成为引领科技潮流的重要力量。而在这一浪潮中,中国的AR公司正以其独特的魅力和创新力,崭露头角。 中国的AR市场正在迎来前所未有的发展机遇。如今&…...
苍穹外卖笔记-07-菜品管理-增加、删除、修改、查询分页还有菜品起售或停售状态
菜品管理 1 新增菜品1.1 需求分析与设计1.2 代码开发文件上传新增菜品实现 1.3 功能测试 2 菜品分页查询2.1 需求分析和设计2.2 代码开发设计DTO类设计VO类Controller层Service层Mapper层 2.3 功能测试 3 删除菜品3.1 需求分析和设计3.2 代码开发Controller层Service层Mapper层…...
oracle dataguard 从库 MRP 进程的状态是 WAIT_FOR_GAP
因主库归档日志未备份直接删除后,从库不能更新,19c版本以上,之前未打补丁,使用 RECOVER STANDBY DATABASE FROM SERVICE PRM180;之后,在执行 alter database recover managed standby database using current logfil…...
【C语言】轻松拿捏-联合体
谢谢观看!希望以下内容帮助到了你,对你起到作用的话,可以一键三连加关注!你们的支持是我更新地动力。 因作者水平有限,有错误还请指出,多多包涵,谢谢! 联合体 一、联合体类型的声明二…...
基于Python定向爬虫技术对微博数据可视化设计与实现
基于Python定向爬虫技术对微博数据可视化设计与实现 Design and Implementation of Weibo Data Visualization Based on Python Web Scraping Techniques 完整下载链接:基于Python定向爬虫技术对微博数据可视化设计与实现 文章目录 基于Python定向爬虫技术对微博数据可视化设…...
【QT5】<总览三> QT常用控件
文章目录 前言 一、QWidget---界面 二、QPushButton---按钮 三、QRadioButton---单选按钮 四、QCheckBox---多选、三选按钮 五、margin&padding---边距控制 六、QHBoxLayout---水平布局 七、QVBoxLayout---垂直布局 八、QGridLayout---网格布局 九、QSplitter---…...
Python中的生成器表达式(generator expression)
Python中的生成器表达式(generator expression)是一种类似于列表解析(list comprehension)的语法结构,但它返回的是一个生成器(generator)对象,而不是一个完整的列表。生成器对象是一…...
Responder工具
简介 Responder是一种网络安全工具,用于嗅探和抓取网络流量中的凭证信息(如用户名、密码等)。它可以在本地网络中创建一个伪造的服务(如HTTP、SMB等),并捕获客户端与该服务的通信中的凭证信息。 Responder工…...
gitblit 环境搭建,服务器迁移记录
下载 Gitblit: http://www.gitblit.com/ JDK:gitblit网站显示需要jdk1.7,这里用的1.8。 Git:到官网下载最新版本安装 1). 分别安装JDK,Git,配置环境变量,下载并解压Gitblit 2). 创建代码仓库 …...
设计感网站/软件开发流程
之前写的请移步 http://muchong.com/bbs/viewthread.php?tid11291053说好要写自己调剂之路的,但是由于最近实在是有点懒,再加上个自己给自己找了份工作,自己每天都累成狗了,也就没有心思写了,但是今天早在就下班了&am…...
王者荣誉网站怎么做/营销心得体会感悟300字
【来信】 尊敬的贺老师: 你好,我是烟大计算机学院大一的学生,曾有幸听过您的一节课,我的老师也曾向我们提起过你,我知道您是一位热心的领路人,我这里有一些问题想请教你,希望您能帮我解答一下…...
wordpress文章缩进/西安百度竞价开户
2.Spring Data Solr 入门2.1 Spring Data Solr 简介虽然支持任何编程语言的能力具有很大的市场价值,你可能感兴趣的问题是:我如何将Solr 的应用集成到 Spring 中?可以,Spring Data Solr 就是为了方便 Solr 的开发所研制的一个框架…...
目前做美术的网站以及app/网络营销这个专业怎么样
(下面内容均是来源于网友经验,我只是大自然的搬运工,多谢广大网友) 原因应该是 :上次关机时未正常关机; 表现症状:QQ初始化失败,很多网页打不开,一些应用打不开ÿ…...
自适应网站建设都找全网天下/百度关键词查询排名怎么查
课题名称 电子钟表和显示星期的设计学院(部) 电子与控制工程学院专 业 建筑设施智能技术班 级学生姓名学 号12 月 27 日至 01 月 09 日共 两 周指导教师(签字)11 年 01 月 09 日目录前言………………………………………………………………….1设计题目与要求…………………………...
门户网站开发模板/seo网站排名的软件
最近遇到一个很奇怪的问题,两个项目弹出的dialog背景颜色不一样,一个是黑色的,一个是白色的,最后发现是AndroidManifest.xml文件里面application指定的android:theme设置的样式不一样。 黑色dialog背景效果图: dialog是黑色的时候application指定的样式如下: <!-…...