基本交互
Q、W、E、R指针交互
鼠右+QEWSAD 镜头交互(降升前后左右 平移)
Ctrl
+ Shift
+ N
新建空物体
Alt
+ Shift
+ N
新建空子物体
Ctrl
+Alt
+ F
选中物体移动到镜头前
Ctrl
+ Shift
+ F
选中物体与镜头完全对齐
F
聚焦选中物体,等同于双击物体sss
Alt
+ Shift
+ A
切换物体活动(active)状态
Ctrl
+ Shift
+ A
添加组件(component)
Project 及 Inspector 可以锁定
实战
分辨率适配
- 使用UGUI,设置如下:
- 主
Camera
组件下Projectiong
设置成Orthographic
采用正交。一般建立项目时选择2d即可 Canvas
组件下Canvas Render Mode
设置成Screen space-Camera
让canvas绑定摄像机。Canvas Scaler(Script)
组件下UI Scale Mode
设置成Scale With Screen Size
缩放是根据屏幕来调整。- 同组件下
Reference Resolution
设置成你设置的分辨率,比如iphone5:640*960
、iphone6:750*1334
、iphoneX:828*1792
。 - 同组件下
Screen Match Mode
设置成需要的情况,Match Width Or Height:根据宽高
、Expand:全拉伸
、Shink:整体缩放
。
- 主
2.部分背景设为11361136 在iphone5,6上依然会有白边,目前解决方案是背景设为11381138。
3.建议美术CG与背景出图大小为,1024*1024
(不重要的背景可512*512
通过拉伸显示)。
SpriteRenderer
(场景_UI)和Image
(Canvas_UI)的区别
两者差别不大,只是在绘制时有细微差别,结论是,ui不动的尽量用Image
,而要游戏内的元素用SpriteRenderer
,其实也就是直接把素材拖入场景
【注意】:代码中修改资源会导致资源永久改变
存初始值,在OnDisable()中修改回去;
脚本
声明
// - - - - - - 枚举
public enum Animal {Dog,Cat} // public也要写上
public Animal myAnimal;
// - - - - - - 整体类型
[System.Serializable]
public class SpeceShipComponent {
public enum ShipComponentType
{
Weapon,
Storage,
Shield,
Command,
Power,
Structural
}
public ShipComponentType type;
public int hitpoints = 0;
public int armor = 0;
}
public SpeceShipComponent spc;//实例化SpeceShipComponent类型
找物体
GameObject.Find("Cube"); // FindGameObject可能被弃用
GameObject.WithTag("Player"); // FindGameObjectWithTag
显示与激活
public GameObject obj;
void start(){
// 组件为enabled
// 游戏对象为active
// obj.active = true;// 废弃
obj.SetActive(true);
obj.activeSelf.ToString();// 自己本身的激活状态
obj.activeInHierarcy.ToString();// 自己在层级菜单中激活状态
}
// 注意这两种不同的状态,比如一个物体的父节点active为false,即便自己active为ture也不显示
[RequireComponent(typeof(Rigidbody))] // 如果找不到这个组件就自己生成一个
OnEnable();// 组件对勾时调用
OnDisable();// 组件取消对勾时调用或游戏结束时
OnDestory();// 游戏结束时调用;
AnimationCurve // 运动曲线
Transform与坐标系
// 以下方法都在GameObject下的transform下
.Right();//xAxis
.Up();//yAxis
.Forward();//zAxis
.TransFormPoint();// 从自身变换到世界坐标
.TransFormDirection();// 自身坐标到世界坐标变换方向
.localPosition; // 本身坐标
.position; // 世界坐标
.Translate(); // 改变世界
// 旋转 把当前对象只想目标对象
void RotateToTarge(Vector3 targetPos)
{
Vector3 direction = (targetPos - this.transform.position).normalized;// 指向目标方向
Quaternion targetRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.RotateTowards(this.transform.rotation, targetRotation, 45 * Time.deltaTime);
}
键盘
Input.GetKeyDown(KeyCode.Space);
Debug相关
Debug.Log("",obj);// 信息或对象
Debug.LogWarning();
Debug.LogError();
// 画线
Vector3 top = new Vector3(2, 2, 2) + this.transform.position;
Vector3 bottom = new Vector3(-2, -2, -2) + this.transform.position;
Debug.DrawLine(top, bottom,Color.red);
Time类 Random类
// Time类
.deltaTime
.captureFramerate // 游戏世界每秒帧率固定,这个在录屏时很有用
.time //游戏开始时运行的时间,暂停不算
.realtimeSinceStartup // 与.time类型,但是暂停不影响
// Random类
.seed= //设置种子
.value //返回0.0-1.0随机数
.insideUnitCircle //半径为1圆形内随机点
.insideUnitSphere //半径为1球体内随机点
.onUnitSphere //半径为1球体表面随机点
.rotation // 随机角度
.rotationUniform // 随机角度(平均分布)
.Range(min,max) // 在min->max之间随机数
Mathf类
.Ceil() // 向上取整
.Floor() // 向下取整
.Round() // 基本四舍五入,特例:10.5(10)、11.5(12)点前偶数5舍,点前奇数5入
.Sign() // 返回符号,0为正
.clamp(value,min,max)
.clamp(value)
// 曲线变换
.Lerp(a,b,t)// 插值
.LerpAngle() //
.MoveTowards(current,target,delta) // 给定速度求值
.MoveTowardsAngle() //
.SmoothStep()//同Lerp(),只是有淡入淡出
.SmoothDamp()
.SmoothDampAngle()
// 其他
.InverseLerp()//根据当前值求百分比
.Repeat() //重复
.PingPong() //来回
.GammaToLinearSpace() // 颜色上Gamma转线性
.LinearToGammaSpace() // 颜色上线性转Gamma
.PerlinNoise() // 噪声图 区间【0-10】
3d数学基础
点积:求投影,得到的是值
,如果值为0那么两向量垂直
叉积:求垂直向量,得到的是向量
,左手坐标系的方向
Vector3类
.back .down .forward .left .one .right .up .zero // 静态向量
.magnitude // 模
.sqrMagnitude // 模平方
.normalized // 单位向量
Vector3 v1 = new Vector3();
v1.normalized; // 值为v1的单位向量
Vector3.Normalize(v1); //同上,一样的
v1.Normalize(); // v1单位向量化
Vector3.Angle(); // 两个夹角
Vector3.ClampMagnitude(); // 对向量的模进行限制
Vector3.Cross(); // 叉积
Vector3.Distance(); // 两点距离
Vector3.Dot(); // 点积 如果值<0两向量反向
Vector3.Lerp(); // 与Mathf相同
Vector3.MoveTowards(); // 与Mathf相同
Vector3.Cross(); // 叉积
Vector3.OrthoNormalize(); //垂直单位向量 方便的定义自己的坐标轴,???没理解
Vector3.Project(); // 将一个向量投射到另一个向量上的投影微量
Vector3.ProjectOnPlane(); // 将一个向量投射到另一个向量为法线的一个平面上的投影微量
Vector3.Reflect(); // 将一个向量投射到另一个向量为法线的一个平面上生成的反射向量
输入输出
Input类
Input.mousePosition // 鼠标位置向量
Input.GetMouseButton(0);//0:左键 1:右键
常用的方法函数
// -------------- Destory 销毁
DestroyImmediate(obj, true); // 立即删除obj,如果obj是资源的话,退出游戏也会永久删除
DontDestroyOnLoad(obj); // 切换场景不删除obj,
// tip1:如果是组件,那么有关这个组件的实体都会被保存下来
// tip2:如果是子节点,那么这个节点不会被保存下来,如果是父节点这个结点包括子结点都会被保存下来
// -------------- Instantiate生成
Instantiate(obj,Vector3);
// -------------- CompareTag 标签
obj.CompareTag("p1"); // 检测是不是"p1"tag 这个比 obj.tag == "p1"更高效
// -------------- SendMessage 消息推送
obj.BroadcastMessage("hide",false);
obj.SendMessage();
obj.SendMessageUpwards();
// -------------- Invoke 延迟执行
Invoke("create",2f);//延迟2s执行create函数
InvokeRepeating("createCube",2f,1f);//延迟2s执行create函数之后每1s重复一次
IsInvoking("createCube");// 是否有createCube程序执行中
CancelInvoke("createCube");// 取消createCube程序
// -------------- Coroutine 协程
void Start() {
StartCoroutine(Timer()); // 开始协同程序
StartCoroutine("Timer"); // 利用反射的方式也可以
StopCoroutine(createCube());// 停止指定
StopAllCoroutines(createCube());// 停止所有
}
IEnumerator Timer() {
yield return new WaitForSeconds(1.0f); // 停止执行1秒
doSomething();
for (int i = 0; i < 100; i++)
{
// do something;
yield return null;// 停止当前帧
}
doSomething2();
}
yield return WaitForEndOfFrame // 帧结束时,渲染前
yield return WaitForFixedUpdat
yield return Coroutine
UGUI-Rect Transform
pivot
旋转中心轴
Anchors 是与父物体成比例关系的映射,取值0-1
,不能超越父物体,根据父物体改变而影响自身
UGUI-事件
IEventSystemHandler
事件接口:
Pointer
鼠标指针类:
IPointerEnterHandler
:区域进入
IPointerExitHandler
:区域移出
IPointerDownHandler
:区域按下(可以移出范围,通过附加条件分左右键)
IPointerUpHandler
:区域抬起
IPointerClickHandler
:必须在物体本身上完成
Drag
&Drop
拖拽类:
IBeginDragHandler
:开始(drag大于阈值)
IInitializePotentialDragHandler
:区域进入
IDragHandler
:拖动中(持续调用)
IEndDragHandler
:结束
IDropHandler
:脚本放到接受物体的上
Select
点选类:
IUpdateSelectedHandler
:区域进入
ISelectHandler
:选中时
IDeselectHandler
:取消选中时
Input
输入类:
IScrollHandler
:鼠标滚轴
IMoveHandler
:InputManager->Input.GetAxisRaw
IScrollHandler
:InputManager->GetButton
ICancelHandler
:InputManager->GetButton
// 拖拽类
public void OnDrop(PointerEventData eventData)
{
eventData.pointerDrag.name;// 正在拖拽的物体
}
// 点选类
// 点选要其他地方处理下
public void OnPointerDown(PointerEventData eventData)
{
EventSystem.current.SetSelectedGameObject(gameObject); //设置当前为物体选中状态
}
public void OnSelect(PointerEventData eventData)
{
eventData.selectedObject;//当前选中的物体
}
UGUI-组件
text
组件,可以使用如下富文本
<b>text</b> <!--粗体-->
<i>text</i> <!--斜体-->
<size=12>text</size> <!--字号-->
<color=green>text</color> <!--指定颜色-->
<color=#00ff00ff>text</color> <!--自定义颜色-->
Button
public Button btn;
btn.onClick.AddListener(ClickEvent);// 添加一个点击事件
btn.onClick.RemoveListener(ClickEvent);// 删除一个点击事件
void ClickEvent(){
// ...
}
c#
int
等价System.Int32
bool
等价System.Boolean
struct
、enum
var
不用管是什么类型
以上继承于System.ValueTpey
,而他又继承于System.Object
,它是所有类的基类;
命名:方法首字母大写, 变量首字母**小写*,都使用驼峰命名法。
struct
struct Person
{
public int age;
private string name;
internal string fname; // 包内使用
protected string lasatName;
}
enum Days { Monday,Tuesday,Wenesday,Thursday,Friday,Saturday,Sunday}
Console.WriteLine(Days.Monday) // Monday
Console.WriteLine((int)Days.Monday) // 0
enum Days { Monday=2,Tuesday,Wenesday,Thursday,Friday,Saturday,Sunday}
Console.WriteLine((int)Days.Wenesday) // 4
enum
Enum E_EXP {
foo,
bar,
}
///强行转换
E_EXP x = (E_EXP)Enum.parse(typeof(E_EXP),"foo");
objcet、string、dynamic
string s1 = "jiaowei";
string s2 = "bigMan";
string u = "\\\u0066\n"; // 输出\f<回车>
string at = @"C:\Jiaowei\hello.cs"; // 加上@不会处理\转义
//string format 规则:``
string format = "asdfjklafd:{0},asdfj:{1}"
Console.WriteLine(format,s1,s2) // asdfjklafd:jiaowei,asdfj:bigMan
class
class Person
{
int age
public int Age
{
get
{
return age+10;
}
set
{
age =value-10; // value指代使用的时候=右边赋值的值
}
}
}
abstract class Man{ // 抽象类不能被实例化,只能被继承
}
interface
interface ISuper
{
int GetSuper();
}
抽象类与接口的区别:
抽象类是被写的为抽象的属性或方法一定要被继承者重写,而同时其他属性与方法可以被继承使用;
接口里的所有属性与方法都要被实现。
类型转换
隐式转换 显式转换
// == == == == == 隐式转换 从小范围到大;
int i = 10;
long l = i;// 隐式从int->long;
//类的转换
CParent cp = new CChild();
class CParent
{}
class CChild : CParent
{}
// == == == == == 显式转换
double d = 10.05;
int i = (int)d;
CParent cp = new CChild();
try{
CChild cc = (CChild)cp;//类的转换
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
cp is CParent;// True 判断是不是此类型
CChild cc2 = cp as CChild; // as 只使用于引用和可为空类型 不能使用在int、string等
Console.WriteLine(cc2 == null);// True 无法转换的时候会为空
字符串与数字
int i = 100;
string s = i.ToString();
int iFromS = Conver.ToInt32("100");//写非数字会报错
int iFromS2 = Int32.Parse("101");//写非数字会报错
int iFroms3;
bool succeed = Int32.TryParse("jkfls",out iFromS3)//写非数字不会给iFromS3赋值默认为0;
// IConveTible,TypeConventer 继承这些借口可以实现自己类里的一些转换
装箱拆箱 Nullable类型
此操作消耗资源,尽量避免
// 装箱 值->引用 开辟空间放入值
int iToBoxing = 100;
object iBoxed = iToBoxing;
// 拆箱 引用->值 从堆里拿出来放到栈上边
int iUnBoxing = (int)iBoxed;
int? iNullable = null;// 可为空的类型
System.Nullable<int> iNullable2 = 100; // 与上句等价
int i1 = iNullable ?? 123;// ??为当前面为空时取?右边值
Console.WriteLine(i1);// 123
int i2 = iNullable ?? 123;
Console.WriteLine(i2);// 100
条件、循环
// && || 双符号指与js相似,从第一个条件开始计算,如果满足就不执行后面的,即会短路
if(condition1 || condition2 ){
}
// & | 单符号指每个条件都运算,不会短路
if(condition1 | condition2 ){
}
foreach(var a in arr){
}// 如要使用foreach arr必须使用IEnumerable接口 List<T>是可以的
集合类型
数组
// 数组 继承于System.Array
// 一维
int[] n = new int[5];
int[] n1 = new int[5]{1,2,3,4,5};
int[] n2 = new int[]{1,2,3,4,5};
int[] n3 = {1,2,3,4,5};
// 二维数组
string[,] names = new string[5,4];
string[,] names2 = {{"a","b"},{"c","d"}};
// 数组数组类型
byte [][] scores = new byte[5][];//每个长度可以不一样
int [][] number3 = {new int[]{1,2,3},new int[]{4,5,6,7}};//new int[]不能省略
// 有iEmunerable,IEmunerato 可以用foreach()
ArrayList和List
// 继承于System.Collection
ArrayList al = new ArrayList();
al.Add(5);
al.Add(100);
al.Add(5);
al.Remove(5); // 测试时从第一个开始删除
al.Add("jiaowei");
foreach (var e in al)
{
Console.WriteLine(e);
}
List<int> intList = new List<int>();
intList.Add(100);
intList.AddRange(new int[] { 501, 502 });
Console.WriteLine(intList.Contains(200));// False
Console.WriteLine(intList.IndexOf(501);// 1
intList.Insert(1,100);
Hashtable 和 Dictionary
Hashtable ht = new Hashtable();
ht.Add(123, 321);
ht.Add("age", 12);
ht.Add("name", "jiaowei");
ht["age"] // 12
Console.WriteLine(ht["lover"]); // 为空,不报错
Dictionary<string, string> d = new Dictionary<string, string>();
d.Add("name", "tom");
d.Add("lover","muji")
Console.WriteLine(d["age"]); // 报错
// 字典类型在多线程中使用有风险,多线程中最好使用ConcurrentDictionary
SortedList<int, int> sl = new SortedList<int, int>(); // 排序列表,根据key(第一个值)排序
//stack 堆栈 先进后出 封口
//queue 队列 先进先出 不封口
面向对象-继承
class Animal{
pulbic virtual void Bite()// virtual指可以被重写
{
Console.WriteLine("Animal bite");
}
pulbic void BiteMan()// 没virtual相当说这个类的自己的方法
{
Console.WriteLine("Animal bite man");
}
}
sealed class dog:Animal// 如果加上sealed 就是这个类无法被继承
{
public override void Bite() // 重写
{
Console.WriteLine("Dog bite");
}
public new void BiteMan() // 如果子类有同名的话,需要用new,指隐藏父类的方法,要不会重名
{
Console.WriteLine("Dog bite man");
}
}
// 难点:构造函数、override/new
C# 运算符重载
// 类
class Complex
{
public int Number { get; set; }
public static Complex operator +(Complex c1, Complex c2)
{
Complex c = new Complex();
c.Number = c1.Number + c2.Number;
return c;
}
}
// 主函数
Complex c1 = new Complex();
Complex c2 = new Complex();
c1.Number = 11;
c2.Number = 22;
Complex c3 = c1 + c2; // 重载+号
Console.WriteLine(c3.Number);
动态多态
委托
public delegate int NumRefDelegate(ref int num);//声明一个带引用参数委托
public delegate int SayHelloDelegate();//声明一个无参数委托
// 匿名方法 AnonymousMethod
NumRefDelegate nod = delegate(ref int num){
return 2*num;
};
SayHelloDelegate sh = delegate{//无参数委托匿名方法的delegate加不加"()"都可以
Console.WriteLine("Hello");
}
数据结构
// 数组回顾
int[] numC = new int[3];
float[] numD = new float[]{1.2f,2.4f,3.3f,4.4f};
// 泛型集合 非泛型集合
// NameSpace
System.Collections.Generic;
// ----------List<T>;
// List<T> 本质是数组,只是封装了很多方便的方法
List<int> num = new List<int>();
num.Add(1);// 增
num.RemoveAt(0);//删
num[0]=3;// 改
num[0];// 查
num.Count;// 长度
// ----------Dictionary<TKey,TValue>;
Dictionary<string,string> info = new Dictionary<string,string>();
info.Add("name","tom");// 增
info.Remove("name");//删
info["name"]="jerry";// 改
info["name"];// 查
info.Count;// 长度
foreach(var item in info.Keys)
{
info[item];// 值
}
Json 操作
// 插件LitJson、unity自带JsonUtility
// ---------------JsonUtility
// 创建
public class Person {
public string name
public int age;
}
Person p1 = new Person();
p1.name = "tom";
p1.age = 25;
string jsonStr = JsonUtility.ToJson(p1);// 直接对象转换
// 解析
类型 实例名 = JsonUtility.FromJson<类型>();
// ---------------插件LitJson
// ----方法1
// 创建
string jsonStr2 = JsonMapper.ToJson(p1);// 直接对象转换
// 解析
类型 实例名 = JsonMapper.ToObject<类型>();
// ----方法2
// 创建
JsonData cjd = new JsonData();
cjd["name"] = "tom";
cjd["age"] = 12;
//{"name":"tom","age":12}
string jsonStr2 = JsonMapper.ToJson(p1);// 直接对象转换
// 解析
类型 实例名 = JsonMapper.ToObject<类型>();
时间
System.DateTime.Now.ToString();
可选参数
void CalculateSum(int a,int b,params int[] arr)
{
int sum = a+b;
//...
return sum;
}
ref out传引用
void ChangeRef(ref int a){
// 可以不赋值
}
void ChangeOut(out int a){
a=99;// 必须赋值
}
void main(){
int a=1;
int b;
ChangeRef(a);//ok
ChangeOut(a);//ok
//ChangeRef(b);//error 没有初始化
ChangeOut(b); //ok
}
评论