基本组件
组件相关方法和变量
gameObject:当前脚本所挂载的游戏物体
//1、name:物体名称
Debug.Log(gameObject.name);
//2、tag:物体标签
Debug.Log(gameObject.tag);
//3、active:现实状态(比如是否显示)
Debug.Log(gameObject.activeInHierarchy);
//4、static GameObject Find(string path):查找游戏物体方法之一
GameObject mode = GameObject.Find("Assets/pearl.obj");
Debug.Log(mode.name)//
变化组件Transform
属性:
1、childCount:子物体数量
2、parent:父物体的Transform组件
3、root:最高级别父物体
4、position、eulerAngles、localScale
方法:
1、Find(string):查找子物体
2、Translate(Vector3):朝着一个坐标移动
3、Rotate(Vector3):旋转一定角度
4、LookAt(Transform):看向目标
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo : MonoBehaviour
{
private Transform myTransform;
private Transform my2;
void Start()
{
//获取当前游戏物体组件
myTransform = gameObject.GetComponent<Transform>();
//子物体数量
Debug.Log(myTransform.childCount);
//修改父物体名字
myTransform.parent.name = "superCube";
Debug.Log(myTransform.parent.name);
//通过position修改物体位置
myTransform.position = new Vector3(1, 1, 1);
//Find获取子物体
my2 = transform.Find("Assets/pearl.obj");
//全局游戏查找游戏物体
my2 = GameObject.Find("Assets/pearl.obj");
}
// Update is called once per frame
void Update()
{
//使游戏物体一直往x正半轴方向移动
myTransform.position += new Vector3(0.05f, 0, 0);
//使游戏物体一直往x正半轴方向移动
myTransform.Translate(new Vector3(0.05f, 0, 0));
//使游戏物体一直往x正半轴方向旋转
myTransform.Rotate(new Vector3(0.05f, 0, 0));
//LookAt使物体看向指定物体(随着指定物体的移动而旋转)
myTransform.LookAt(GameObject.Find("superCube").transform);
}
}
灯光组件
游戏中一般的默认灯光:
也可以自己创建:
1、Directioal Light:平行光,类似太阳光,整个游戏世界都会被照亮
2、Point Light:点光源
3、Spotlight:聚光灯
4、Area Light面积光源,必须烘培,只对静态物体有效
灯光烘培:提前渲染好,之后不在改变,比如发光的灯泡
静态物体:游戏场景中不会变化,渲染上不会实时计算的物体
1、Type:灯光类型
2、Range:灯光范围
3、Mode:灯光渲染模式:
- 实时:动态的计算灯光.Mode->Mixed,以及窗口右下角Auto Generate Lighting on/off设置
- 烘培:一开始就确定好灯光,后面游戏物体经过身上也不会有光.Mode->Baked
- 混合:静态物体一开始也确定好灯光,但后续游戏物体经过身上就会有光.Mode->Realtime
4、Intensity:光照强度
5、Shadow Type:阴影类型
摄像机组件
1、Background:不使用天空盒(Skybox)下的背景颜色
2、culling Mask(中文模式下为:剔除遮罩):可以看到哪些游戏物体
3、Field of View:视野大小
4、Clipping Planes:画面拍摄的距离区间
将摄像机拖到物体下方,摄像机会随着物体移动而移动(层级)
也可以通过调整摄像机的Transform组件来把摄像机移动到合适位置。
模型网格组件
1、Materials:材质球,可能会有多个的情况
2、Lighting(照明):灯光设置
- Cast Shadows:是否产生阴影
- Receive Shadows:是否接受阴影
控制组件
使用this关键字来代表这个组件自身
属性:
1、enabled:组件是否激活中,也可以通过这个属性来修改激活状态
方法:
1、gameObject.GetComponent():获取组件
2、gameObject.AddComponent():添加组件
3、Destroy(Component):删除指定组件,也可以删除游戏物体GameObject
public Demo myDemo1;
public Demo myDemo2;
void Start()
{
//获取当前组件
myDemo1 = GetComponent<Demo2>();//Demo2为另一个组件
Debug.Log(this.myDemo1.name);
//给myDemo2添加Demo2组件
myDemo2 = GetComponent<Demo2>();
Debug.Log(this.myDemo2.name);
enabled = false;//void Start()中执行后,后续的代码会正常执行,但是void Update()里不再执行
//删除myDemo1
Destroy(myDemo1);
//删除当前游戏物体
Destroy(GameObject);
}
键鼠交互
鼠标交互:
1、Input.GetMouseButton(int):鼠标是否一直按下某个按键,如果持续按压会返回true,整型参数0代表左键,1代表右键
2、Input.GetMouseDown(int):鼠标是否按下某个按键
3、Input.GetMouseUp(int):鼠标是否弹起某个按键
4、Input.GetAxis(“Mouse ScrollWheel”):鼠标滑轮滚动,向上返回0.1,向下返回-0.1
键盘交互:
1、Input.GetKey(KeyCode.A):键盘是否一直按下某个键位,如果一直按压会一直返回true
2、Input.GetKeyDown(KeyCode.A):键盘是否会按下某个键位,只返回一次true
3、Input.GetKeyUp(KeyCode.A):键盘是否会弹起某个键位,只返回一次true
Input Manager(Edit -> Project setting -> Input Manager):
之前鼠标滚轮操作即是对应此处Mouse ScrollWheel,可以调整名称及其他设置:
Input Manager中的Horizontal(水平)和Vertical(竖直)可实现物体的平滑移动:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo : MonoBehaviour
{
private float speed = 0.05f;
void Start(){}
void Update()
{
//KeyCodeMove();
InputManagerMove();
}
//直接加固定浮点数移动
private void KeyCodeMove()
{
if (Input.GetKey(KeyCode.W))
{
transform.position += new Vector3(0, 0, speed);
}
if (Input.GetKey(KeyCode.S))
{
transform.position += new Vector3(0, 0, -speed);
}
if (Input.GetKey(KeyCode.A))
{
transform.position += new Vector3(-speed, 0, 0);
}
if (Input.GetKey(KeyCode.D))
{
transform.position += new Vector3(speed, 0, 0);
}
}
//基于输入管理器的移动
private void InputManagerMove()
{
//水平方向
float h = Input.GetAxis("Horizontal");
//竖直方向
float v = Input.GetAxis("Vertical");
if (h != 0 || v != 0)
{
transform.position += new Vector3(h, 0, v) * speed;
}
}
}
刚体
一、重力(Edit -> Project Setting -> Physics -> Gravity):一般为y轴方向,-9.81的重力加速度。
二、刚体组件(RigidBody):游戏物体需要携带刚体组件才能进行物理计算:
1、Mass:刚体质量,单位kg,参与碰撞计算
2、Drag:空气阻力
3、Angular Drag:物体受力旋转的阻力
4、Use Gravity:是否使用重力
5、Is Kinematic:是否受物理影响
6、Interpolate:插值,平滑方式
三、刚体常用方法
1、施加直线方向的力:
Rigidbody.AddForce(Vector3, ForceMode):相对于世界坐标施加一个力
- Vector3:力的方向和大小
- ForceMode:力的模式
①、Acceleration:添加一个可持续的力,忽略质量,固定值1
②、Force:添加一个可持续的力,使用其质量
③、VelocityChange:添加一个瞬间爆发的力,忽略质量,固定值1
④、Impulse:添加一个瞬间爆发的力,使用其质量
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo : MonoBehaviour
{
private Rigidbody myRigidbody;
void Start()
{
//获取组件
myRigidbody = GetComponent<Rigidbody>();
myRigidbody.velocity = new Vector3(0, 10, 0);
}
void Update()
{
//RigidbodyMove();
//Move();
}
private void Move()
{
//水平方向玩家的操作程度 左-1 右1 中间有过渡
//GetAxisRaw 不平滑
//float h = Input.GetAxisRaw("Horizontal");
float h = Input.GetAxis("Horizontal");
// 垂直方向玩家的操作程度 上1 下-1 中间有过渡
float v = Input.GetAxis("Vertical");
//transform.position += new Vector3(h, 0, v) * 0.2f;
//等价
//transform.Translate(new Vector3(h, 0, v) * 0.2f);
//施加按键方向的力
myRigidbody.MovePosition(transform.position+new Vector3(h, 0, v) * 1f);
Debug.Log(myRigidbody.velocity);
if (Input.GetKeyDown(KeyCode.Space))
{
//myRigidbody.AddRelativeForce(new Vector3(0, 1, 0) * 10f,ForceMode.Impulse);
//myRigidbody.AddTorque(new Vector3(0, 1, 0) * 1000);
}
//myRigidbody.AddTorque(new Vector3(0, 1, 0) * 1000000);
}
private void RigidbodyMove()
{
//水平方向玩家的操作程度 左-1 右1 中间有过渡
//GetAxisRaw 不平滑
float h = Input.GetAxisRaw("Horizontal");
//垂直方向玩家的操作程度 上1 下-1 中间有过渡
float v = Input.GetAxisRaw("Vertical");
//transform.position += new Vector3(h, 0, v) * 0.2f;
//transform.Translate(new Vector3(h, 0, v) * 0.2f);
myRigidbody.AddForce(new Vector3(h, 0, v) * 20f);
}
}
刚体碰撞
例如子弹打到会掉血的情况
碰撞前提:1、双方都有碰撞体组件;2、必须有一方有刚体组件
碰撞函数:
类似Start、Update,都是Unity内置函数,但不是生命周期函数
OnCollisionEnter(Collision collsion):碰撞进入、也就是碰撞的瞬间;Collision:碰撞信息,内含发生碰撞的另一个游戏物体gameObject、rigidBody等属性
OnCollisionStay(Collision collsion):碰撞中
OnCollisionExit(Collision collsion):碰撞退出
private void OnCollisionEnter(Collision other)//other表示另外的与之碰撞的物体
{
if(other.gameObject.name == "head")
{
Debug.Log("掉血了");
}
}
RighdBody中来设置刚体的碰撞检测,主要用来防止运动过快导致的穿模问题:
Collision Detection:碰撞检测方式
- Discrete:离散检测,检测频率低,但是性能较高。不用于高速运动的物体
- Continuous:连续检测,防止对象穿过静态碰撞体。用于被高速物体撞击
- Continuous Dynamic:动态连续检测,防止对象穿过静态碰撞体以及设置为Continuous或Continuous Dynamic的刚体。用于自身高速运动的物体
- Continuous Speculative:两个Continuous的结合,但是性能变低
除了Discrete,其他碰撞检测方式都只支持内置的碰撞体
刚体触发
例如踩到燃烧的草地会掉血而又不会与草地发生碰撞,即玩家与草地有接触但不产生物理效果(需要穿模)
触发前提:1、两个物体都有碰撞体组件;2、其中一个物体碰撞器的IsTrigger属性需要选中;3、其中一个物体需要有刚体组件。
OnTriggerEnter(Collider collsion):触发进入、也就是触发的瞬间;Collider:另一个游戏物体的碰撞体组件
OnTriggerStay(Collidercollsion):接触中
OnTriggerExit(Collidercollsion):接触结束
碰撞体
碰撞体组件(Collider),用蓝色的线框包围游戏物体,作为物理计算时的物体真实边缘
1、Box Collider:盒型碰撞体、Capsule Collider:胶囊型碰撞体、Sphere Collider:球型碰撞体
2、Is trigger:触发器,判定有无碰撞发生
3、Material:物理材质,与摩擦力,弹性系数等有关
常见用法:
1、一个物体如果需要重力掉落或者碰撞运动,需要添加刚体和碰撞体,刚体决定运动,碰撞体决定计算边缘
2、一个物体如果是固定物体,不参与运动但参与碰撞计算,则不用添加刚体需要添加碰撞体
3、大多数情况不止会添加刚体而不添加碰撞体,这会使物体无限下落,无法碰撞其他游戏物体
如图所示,若是不规则模型,需要比较精确的设计,则可以添加Mesh Collider(网格碰撞体),然后添加模型对应部位的Mesh:
物理材质
物理财政和模型材质无关,物理材质是用于调整碰撞体对象的摩擦力和弹性效果
1、Dynamic Friction:动摩擦力,值为0时光滑,为1时物体将很快停止运动
2、Static Friction:静摩擦力
3、Bounciness:表面弹性,值为0时对象无弹力,值为1时对象为具有完全弹性的理想刚体
4、Friction Combine:发生碰撞的两个碰撞体对象的摩擦力混合方式
- Maximum:取两个对象摩擦力的最大值
- Multiply:取两个对象摩擦力相乘后的值
- Minimum:取两个对象摩擦力的最小值
- Average:取两个对象摩擦力的平均值
5、Bounce Combine:发生碰撞的两个碰撞体对象的弹力混合方式,其参数方法同上
可以在文件中新建一个物理材质:
调整相关数值后拖入碰撞体: