目录
perspective透视模式(近大远小,一般用于3D游戏)
orthographic 正交摄像机(一般用于2D游戏制作)
生命周期函数
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//当前类对象被创建时才会调用
//类似构造函数 创建时进行一些初始化操作
void Awake()
{
print("Awake");
}
//当对象被激活时调用
void OnEnable()
{
print("Onenable");
}
//用于初始化信息 但比Awake要晚一点
//在对象进行第一次帧更新之前执行
void Start()
{
print("Start");
}
//它主要是用于进行物理更新
//它的时间间隔是可在project setting中的 Time里去设置的
void FixedUpdate()
{
print("FixedUpdate");
}
//处理游戏核心逻辑性更新的函数,每次循环执行一次
void Update()
{
print("Update");
}
//一般用来更新摄像机位置
//update和Lateupdate之间 Unity进了一些处理处理动画相关的更新
void LateUpdate()
{
print("LateUpdate");
}
//对象失活时调用
void OnDisable()
{
print("Ondisable");
}
//对象被删除时调用
void OnDestroy()
{
print("OnDestroy");
}
}
Inspector窗口可编辑的变量
1.私有和保护类无法显示编辑
2.可以使私有和保护类在窗口中显示编辑,要加上强制序列化字段:
[SerializeField]
private int i1;
3.公共类可以显示编辑
4.公共类也可以使其不能在窗口中显示编辑,要加上隐藏字段:
[HideInInspector]
public string s;
5.大部分类型都能显示编辑:
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlTypes;
using UnityEngine;
public enum E_TestEnum
{
Normal,
Player,
}
public struct MyStruct
{
public int x;
public int y;
}
public class MyClass
{
public int age;
public string name;
}
public class Lesson2 : MonoBehaviour
{
//可以被显示
public int[] array;
public List<int> list;
public E_TestEnum type;
public GameObject gameObj;
//不能被显示
public Dictionary<int, string> dic;//字典
public MyStruct myStruct;//自定义类型
public MyClass myClass;
}
6.使自定义类型能够显示编辑,在类定义之前加上[System.Serializable]:
[System.Serializable]
public struct MyStruct
{
public int x;
public int y;
}
7.其它补充:
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlTypes;
using UnityEngine;
public class Lesson2 : MonoBehaviour
{
//文字标签分组
[Header("基础属性")]
public int age=10;
public string name;
[Header("战斗属性")]
public int atk;
public int def;
//悬停注释
[Tooltip("闪避")]
public int miss;
//间隔
[Space()]
public int crit;
//显示滑条范围
[Range(0,10)]
public float luck;
//多行显示字符串,默认为三行
[Multiline()]
public string s1;
[TextArea(3,4)]
public string s2;
//添加快捷方法,第一个参数为按钮名,第二个为方法名(不能带参数)
[ContextMenuItem("重置","Test")]
public int Money;
private void Test()
{
Money = 1;
}
//为方法添加特性,使其能在Inspector中执行
[ContextMenu("测试")]
private void testFun()
{
print("测试成功");
}
}
注意:
1. Inspector窗口中的变量关联的就是对象的成员变量,运行时改变他们就是在改变成员变量
2.脚本部署完毕后,再改变脚本中变量的默认值,窗口中的值也不会改变,可以先移除脚本在拖拽上去
3.如果需要使用运行中的值可以先copy再paste
MonoBehavior中的重要内容
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class Lesson3 : MonoBehaviour
{
void Start()
{
//1.获取依附的Gameobject
print(this.gameObject.name);//this可省略,可直接用gameObject获取
//2.获取依附的Gameobject的位置信息
//得到对象位置信息
print(this.transform.position);//位置
print(this.transform.eulerAngles);//角度
print(this.transform.lossyScale);//缩放大小
//this.gameObject.transform 与 this.transform相同,故使用后者,this也可省
//控制脚本是否激活:
this.enabled = true;
this.enabled = false;
//得到依附对象上挂载的其它脚本
public Lesson2 Other;
print(Other.gameObject.name);
//1.得到自己挂载的单个脚本
//根据脚本名获取,若没有对应脚本则获取失败返回空值
Lesson3_Test t = this.GetComponent("Lesson3_Test") as Lesson3_Test;//父类装到子类需转换类型
print(t);
//根据Type获取
t = this.GetComponent(typeof(Lesson3_Test)) as Lesson3_Test;
print(t);
//根据泛型获取 建议使用泛型获取 因为不用二次转换
t = this.GetComponent<Lesson3_Test>();
print(t);
//2.得到自己挂载的同种类型的多个脚本
Lesson3[] arr = this.GetComponents<Lesson3>();
List<Lesson3> l = new List<Lesson3>();
this.GetComponents<Lesson3>(l);
//3.得到子对象挂载的脚本,它默认也会找自己身上是否有挂载了该脚本
t = this.GetComponentInChildren<Lesson3_Test>();//圆弧括号内的参数为true/false,若为true则子对象失活也能查找到该脚本,默认为false
//得子对象 挂载脚本 多个
Lesson3_Test[] lts = this.GetComponentsInChildren<Lesson3_Test>(true);
print(lts.Length);
List < Lesson3_Test > list2 = new List<Lesson3_Test>(); this.GetComponentsInChildren<Lesson3_Test>(true, list2);
print(list2.Count);
//4.得到父对象挂载的脚本(它默认也会找自己身上是否挂载该脚本)
t = this.GetComponentInParent<Lesson3_Test>();
print(t);
lts = this.GetComponentsInParent < Lesson3_Test > (); print(lts.Length);
//5.尝试获取脚本
if(this.TryGetComponent<Lesson3_Test>(out t))
{
//相关处理
}
}
}
GameObject知识点
成员变量
//名字
print(this.gameObject.name);
this.gameObject.name = "改名";
print(this.gameObject.name);
//是否激活
print(this.gameObject.activeSelf);
//是否为静态
print(this.gameObject.isStatic);
//层级(int类型)
print(this.gameObject.layer);
//标签(string类型)
print(this.gameObject.tag);
//transform
print(this.gameObject.transform);//GameObject中也有transform
//但Mono中也有所以与this.transform效果相同
静态方法
创建对象
可以通过GameObject.CreatePrimitive方法创建已有几何体,并且可对其内容进行修改:
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
obj.name = "创建的立方体";
查找对象
通过名字查找单个对象
使用GameObject.Find()方法,但是效率低下,会遍历场景中所有对象
GameObject obj2 = GameObject.Find("创建");
if (obj2 != null)
{
print("未找到对应对象");
}
else
{
print(obj2.name);
}
通过Tag来查找单个对象
使用GameObject.FindGameObjectsWithTag("Tagname")或者GameObject.FindWithTag("Tagname")来查找,二者相同
GameObject obj3 = GameObject.FindWithTag("Player");
if (obj3 != null)
{
print("根据tag找到的对象" + obj3.name);
}
else
{
print("根据tag未找到对象");
}
以上两种查找方式都找不到失活的对象,而且若查找到多个符合条件的对象无法确定返回的是哪一个
通过Tag查找多个对象
使用GameObject.FindGameObjectsWithTag("Tagname"),也找不到失活的对象
GameObject[] objs = GameObject.FindGameObjectsWithTag("Player");
print(objs.Length);
找到场景中挂载某个脚本
使用GameObject.FindObjectOfType<>(),效率更加低下,遍历场景中的对象还要遍历对象上的所有脚本。
Lesson4 o = GameObject.FindObjectOfType<Lesson4>();
print(o.gameObject.name);
实例化对象(克隆对象)的方法
作用是根据已有的GameObject对象,创建出一个与之一样的对象。
一种是克隆场景上已有的对象,另一种是克隆预设体,将对象或者预设体拖拽过去即可。
使用GameObject.Instantiate()函数,该函数属于Object类中,故如果继承了MonoBehavior类使用时可以不加上GameObject直接使用
GameObject obj5 = GameObject.Instantiate(pre);
删除对象的方法
使用GameObject.Destroy("要删除的对象名称",延迟删除时间)方法,该函数也是在Object类中,如果继承了MonoBehavior类也可以直接使用。
GameObject.Destroy(obj5,5);
Destroy还可以删除指定的脚本对象。
Destroy(this);
注意:这个Destroy方法 不会马上移除对象 只是给这个对象加了一个移除标识
般情况下 它会在下一帧时把这个对象移除并从内存中移除
若想立即删除可以使用GameObject.DestroyImmediate()函数,如果没有特殊需求就不需要使用这个方法,由于Destroy方法是异步的可以减少游戏的卡顿
过场景不移除
默认情况下,切换场景时,场景上的所有对象都会被自动删除,若希望某个对象在过场景时不被删除,使用GameObject.DontDestroyOnLoad();
GameObject.DontDestroyOnLoad(this.gameObject);
//当前脚本所依附的对象过场景不删除
成员方法
创建空物体
new一个GameObject就是在创建一个空物体
GameObject obj6 = new GameObject();
GameObject obj7 = new GameObject("创建的空物体");
GameObject obj8 = new GameObject("创建挂脚本的空物体", typeof(Lesson1), typeof(Lesson2));
为对象添加脚本
继承了MonoBehavior的脚本,是不能够new出来的,若要动态添加继承了MonoBehavior的脚本在某一个对象上则直接使用AddComponent:
Lesson2 l2 = obj6.AddComponent(typeof(Lesson2)) as Lesson2;
Lesson1 l1 = obj6.AddComponent<Lesson1>();//使用泛型更方便
得到脚本的成员方法和继承MonoBehavior的类得到脚本的方法相同,故不再赘述
标签比较
if (this.gameObject.CompareTag("Player"))//括号内也可以写成this.gameObject.tag == "Player"
{
print("该对象的标签是Player");
}
else
{
print("该对象的标签不是Player");
}
设置失活/激活
参数传false失活,true激活
obj6.SetActive(false);
obj7.SetActive(false);
obj8.SetActive(false);
次要的成员方法
了解即可,不建议使用,效率低
this.gameObject.SendMessage("函数名");//自己查找执行该函数
this.gameObject.BroadcastMessage("函数名");//自己和自己的子对象都查找执行该函数
this.gameObject.SendMessageUpwards("函数名");//自己和自己的父对象都查找执行该函数
这些要查找执行的函数都可以带参数,参数写在函数名后面即可
时间相关_Time
时间缩放比
//时间停止
Time.timeScale =0;
//回复正常
Time.timeScale = 1;
//2倍速
Time.timeScale=2;
帧间隔时间
最近的一帧用了多长时间
受scale影响
print("受scale影响的时间"+Time.deltaTime);
不受scale影响
print("不受scale影响的时间" + Time.unscaledDeltaTime);
帧间隔时间,主要用来计算位移,要根据需求选择计算的时间间隔,如果希望游戏暂停时就不动的就用前者,如果希望不受暂停影响就用后者。
游戏开始到现在的时间
受scale影响
print("游戏开始到现在的"+Time.time);
不受scale影响
print("不受scale影响的游戏开始到现在的时间"+Time.unscaledTime);
物理帧时间间隔
受scale影响
print(Time.fixedDeltaTime);
不受scale影响
print(Time.fixedUnscaledDeltaTime);
帧数
从开始到现在游戏跑了多少帧,即多少次循环
print(Time.frameCount);
Transform
游戏对象(Gameobject)位移、旋转、缩放、父子关系、坐标转换等相关操作都由它处理
是Unity提供的极其重要的类