本书为TPS案例
CTRL+D
复制预设,按住V
可以边缘对齐F
,最终移动的对象可以按两次FQ
, W
, E
, R
, T
Z
,局部/全局转换X
模式 | 内容 |
---|---|
Shaded | 3D模型表面附着纹理 |
Wireframe | 消除纹理,仅呈现3D模型的Mesh |
Shaded Wireframe | 同时呈现阴影和网格 |
Miscellaneous | 混合模式,Shadow Cascades, Render Paths, Alpha Channel, Overdraw, Mipmaps |
Deferred | 只看到过滤后的Albedo, Specular, Smoothness以及Normal纹理 |
Global Illumination |
新建一个物件而后拖到Project里面
种类 | 效果 |
---|---|
平行光 | Y轴通常为100,不受位置影响 |
点光源 | Range属性改变照射范围 |
聚光灯 | 圆锥形的光 |
区域光 | 一般是四边形,烘焙后才能呈现,不是实时的 |
skybox
,skydome
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
void Start(){
tr = GetComponent();
}
void Update(){
tr.Translate(Vector3.forward * movespeed * v * Time.deltaTime, Space.Self);
// tr.position += new Vector3(0,0,1);
}
Vector3.Lerp(起始位置,结束位置,浮点格式时间)
线性内插平滑LateUpdate
,保证摄像机移动在角色移动之后// 1. control height & dist
tr.position = Vector3.Lerp(tr.position,
targetTr.position - (targetTr.forward * dist) + (Vector3.up * height),
Time.deltaTime * dampTrace);
// 2. look at object
tr.LookAt(targetTr.position)
Animation组件是Unity将动画类型设置为Legacy动画系统时自动添加的组件,保存了相应游戏模型包含的动画片段列表,不存在于该列表的动画将不会运行。
// p104
[System.Serializable]
public class Anim{
public AnimationClip idle;
}
public class PlayerCtrl: MonoBehaviour{
public Anim anim;
public Animation _animation;
void Start(){
_animation = GetComponentInChildren();
_animation.clip = anim.idle;
_animation.Play();
}
void Update(){
if(v >= 0.1f){
_animation.CrossFade(anim.runForward.name, 0.3f);
}
}
}
Directional Light->Shadow Type
物理模拟,不必直接修改Position
属性 | 含义 |
---|---|
Mass | 相对质量 |
Drag/Angular Drag | 摩擦系数,旋转摩擦系数 |
Use Gravity | 重力 |
is Kinematic | 勾选则不受物理引擎影响 |
Interpolate,Extrapolate | |
Collisition Detection | Discrete->Continuous->Continuous Dynamic |
Freeze Position/Rotation | 阻止某一个方向改变 |
名称 | 含义 |
---|---|
Box Collider | 最常用的 |
Sphere Collider | 最快的 |
Capsule Collider | 人形 |
Mesh Collider | 精细 |
Wheel Collider | 车轮 |
Terrain Collider | 地形 |
OnCollisionEnter
,OnCollisionStay
,OnCollisionExit
OnTriggerEnter
,OnTriggerStay
,OnTriggerExit
void OnCollisionEnter(Collision coll){
if(coll.collider.tag == "BULLET"){
Destroy(coll.gameObject);
}
}
public class FireCtrl:MonoBehaviour{
public GameObject bullet;
public Transform firepos;
void CreateBullet(){
Instantiate(bullet, )
}
}
添加NavMeshAgent
使其可以追踪玩家
使用Coroutine进行定时判断
void Start () {
StartCoroutine(this.CheckMonsterState());
StartCoroutine(this.MonsterAction());
}
IEnumerator CheckMonsterState(){
while(!isDie){
yield return new WaitForSeconds(0.2f);
}
}
使用enum进行状态表示
追踪
void Start () {
nvAgent = this.gameObject.GetComponent ();
//nvAgent.destination = playerTr.position;
animatior = this.gameObject.GetComponent();//要在开启协程之前
}
IEnumerator MonsterAction(){
while(!isDie){
switch(monsterState){
case MonsterState.idle:
nvAgent.Stop();
break;
case MonsterState.trace:
nvAgent.destination = playerTr.position;
nvAgent.Resume();
break;
case MonsterState.attack:
nvAgent.Stop();
break;
}
yield return null;
}
}
添加RigidBody和Collision,在coll位置添加血迹
GameObject blood1 = (GameObject) Instantiate(bloodEffect, coll.transform.position, Quaternion.identity);
Destroy(blood1, 2.0f);
void PlayerDie(){
GameObject[] mosters = GameObject.FindGameObjectsWithTag("monster");
foreach(GameObject monster in mosters){
monster.SendMessage("OnPlayerDie", SendMessageOptions.DontRequireReceiver);
}
Debug.Log("END");
}
//playerCtrl
public delegate void PlayerDieHandler();
public static event PlayerDieHandler OnPlayerDie;
if(hp <= 0){
OnPlayerDie();
}
//monsterCtrl
void OnEnable(){
PlayerCtrl.OnPlayerDie += this.OnPlayerDie;
}
void OnDisable(){
PlayerCtrl.OnPlayerDie -= this.OnPlayerDie;
}
gameUI = GameObject.Find("GameUI").GetComponent()
public static GameMgr instance = null;
void Awake(){
instance = this;
}
取代每次都要先访问挂载对象才能访问类.
如果在移动平台动态生成对象或者预设,设备负荷会非常高,应该先start生成而后直接取用.
using System.Collections.Generic;// List
public ListmonsterPool = new List();
for(int i = 0; i < maxMonster; ++i){
GameObject monster = (GameObject)Instantiate(monsterPrefab);
monster.name = "Monster_" + i.ToString();
monster.SetActive(false);//先设置为false
monsterPool.Add(monster);
}
//
if(isGameOver) break;
foreach(GameObject monster in monsterPool){
if(!monster.activeSelf){
int idx = Random.Range(1,points.Length);
monster.transform.position = points[idx].position;
monster.SetActive(true);
break;
}
}
// 然后在怪兽挂掉的地方添加一个协程放回对象池.