Unity-C#学习

一. Unity C#初级编程

1. 作为行为组件的脚本

这里将脚本挂载到物体上,控制他本身材质的颜色…猜测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using UnityEngine;
using System.Collections;

public class ExampleBehaviourScript : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
GetComponent<Renderer> ().material.color = Color.red;
}
if (Input.GetKeyDown(KeyCode.G))
{
GetComponent<Renderer>().material.color = Color.green;
}
if (Input.GetKeyDown(KeyCode.B))
{
GetComponent<Renderer>().material.color = Color.blue;
}
}
}

2. 变量与函数

定义变量前需要确定类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using UnityEngine;
using System.Collections;

public class VariablesAndFunctions : MonoBehaviour
{
int myInt = 5;


void Start ()
{
myInt = MultiplyByTwo(myInt);
Debug.Log (myInt);
}


int MultiplyByTwo (int number)
{
int ret;
ret = number * 2;
return ret;
}
}

3. 约定与语法

即代码规范

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using UnityEngine;
using System.Collections;

public class BasicSyntax : MonoBehaviour
{
void Start ()
{
Debug.Log(transform.position.x);

if(transform.position.y <= 5f)
{
Debug.Log ("I'm about to hit the ground!");
}
}
}

4. IF语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using UnityEngine;
using System.Collections;

public class IfStatements : MonoBehaviour
{
float coffeeTemperature = 85.0f;
float hotLimitTemperature = 70.0f;
float coldLimitTemperature = 40.0f;


void Update ()
{
if(Input.GetKeyDown(KeyCode.Space))
TemperatureTest();

coffeeTemperature -= Time.deltaTime * 5f;
}


void TemperatureTest ()
{
// 如果咖啡的温度高于最热的饮用温度...
if(coffeeTemperature > hotLimitTemperature)
{
// ... 执行此操作。
print("Coffee is too hot.");
}
// 如果不是,但咖啡的温度低于最冷的饮用温度...
else if(coffeeTemperature < coldLimitTemperature)
{
// ... 执行此操作。
print("Coffee is too cold.");
}
// 如果两者都不是,则...
else
{
// ... 执行此操作。
print("Coffee is just right.");
}
}
}

5. 循环

a. For循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using UnityEngine;
using System.Collections;

public class ForLoop : MonoBehaviour
{
int numEnemies = 3;


void Start ()
{
for(int i = 0; i < numEnemies; i++)
{
Debug.Log("Creating enemy number: " + i);
}
}
}

b. While循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using UnityEngine;
using System.Collections;

public class WhileLoop : MonoBehaviour
{
int cupsInTheSink = 4;


void Start ()
{
while(cupsInTheSink > 0)
{
Debug.Log ("I've washed a cup!");
cupsInTheSink--;
}
}
}

c. DoWhile循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using UnityEngine;
using System.Collections;

public class DoWhileLoop : MonoBehaviour
{
void Start()
{
bool shouldContinue = false;

do
{
print ("Hello World");

}while(shouldContinue == true);
}
}

d. Foreach循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
using System.Collections;

public class ForeachLoop : MonoBehaviour
{
void Start ()
{
string[] strings = new string[3];

strings[0] = "First string";
strings[1] = "Second string";
strings[2] = "Third string";

foreach(string item in strings)
{
print (item);
}
}
}

6. 作用域和访问修饰符

ScopeAndAccessModifiers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using UnityEngine;
using System.Collections;

public class ScopeAndAccessModifiers : MonoBehaviour
{
public int alpha = 5;


private int beta = 0;
private int gamma = 5;


private AnotherClass myOtherClass;


void Start ()
{
alpha = 29;

myOtherClass = new AnotherClass();
myOtherClass.FruitMachine(alpha, myOtherClass.apples);
}


void Example (int pens, int crayons)
{
int answer;
answer = pens * crayons * alpha;
Debug.Log(answer);
}


void Update ()
{
Debug.Log("Alpha is set to: " + alpha);
}
}

AnotherClass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using UnityEngine;
using System.Collections;

public class AnotherClass
{
public int apples;
public int bananas;


private int stapler;
private int sellotape;


public void FruitMachine (int a, int b)
{
int answer;
answer = a + b;
Debug.Log("Fruit total: " + answer);
}


private void OfficeSort (int a, int b)
{
int answer;
answer = a + b;
Debug.Log("Office Supplies total: " + answer);
}
}

7.Awake 和 Start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using UnityEngine;
using System.Collections;

public class AwakeAndStart : MonoBehaviour
{
//只需挂载脚本,而不需要勾选
void Awake ()
{
Debug.Log("Awake called.");
}

//勾选了,才会执行这里
void Start ()
{
Debug.Log("Start called.");
}
}

8. UpdateFixedUpdate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using UnityEngine;
using System.Collections;

public class UpdateAndFixedUpdate : MonoBehaviour
{
/*按照固定时间调用
*调用之后,会立刻进行任何必要的物理计算
*因此任何影响刚体(即物理对象)的动作,都应该使用FixedUpdate()执行
*最好使用力来定义移动
**/
void FixedUpdate ()
{
Debug.Log("FixedUpdate time :" + Time.deltaTime);
}

/*游戏中每一帧的调用
*基本上只要需要变化或者调整
*非物理对象的移动
*简单的计时器
*输入监测
*!!请注意,update并不是按照固定时间调用的,帧与帧之间的处理时间不一致会导致Update()调用间隔
**/

void Update ()
{
Debug.Log("Update time :" + Time.deltaTime);
}
}

VST中在任何想要插入函数的地方按住 Ctrl+Shift+M

9. 矢量数学

1
2
Vector3.Dot(VectorA,VectorB)
Vector3.Cross(VectorA,VectorB)//用于坦克扭矩..

10. 启用和禁用组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using UnityEngine;
using System.Collections;

public class EnableComponents : MonoBehaviour
{
private Light myLight;


void Start ()
{
myLight = GetComponent<Light>();
}


void Update ()
{
if(Input.GetKeyUp(KeyCode.Space))
{
//这个逻辑很棒,自动取反不需要if else啥的
myLight.enabled = !myLight.enabled;
}
}
}

11. 激活游戏对象

ActiveObjects

1
2
3
4
5
6
7
8
9
10
using UnityEngine;
using System.Collections;

public class ActiveObjects : MonoBehaviour
{
void Start ()
{
gameObject.SetActive(false);
}
}

CheckState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using UnityEngine;
using System.Collections;

public class CheckState : MonoBehaviour
{
public GameObject myObject;


void Start ()
{
Debug.Log("Active Self: " + myObject.activeSelf);
Debug.Log("Active in Hierarchy" + myObject.activeInHierarchy);
}
}

如果它的父对象被隐藏,需要先将父对象设置为激活状态,再操作子对象

12. Translate 和 Rotate

平移与旋转常用函数

TransformFunctions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using UnityEngine;
using System.Collections;

public class TransformFunctions : MonoBehaviour
{
public float moveSpeed = 10f;
public float turnSpeed = 50f;


void Update ()
{
//这样会每帧,向z轴方向下移动,每帧移动1单位
//transform.Translate(new Vector3(0,0,1))
if(Input.GetKey(KeyCode.UpArrow))
//按照每秒多少米的速度移动
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);

if(Input.GetKey(KeyCode.DownArrow))
transform.Translate(-Vector3.forward * moveSpeed * Time.deltaTime);
//Vector3.up表示围绕哪个轴转,
//turnSpeed旋转速度
if(Input.GetKey(KeyCode.LeftArrow))
transform.Rotate(Vector3.up, -turnSpeed * Time.deltaTime);

if(Input.GetKey(KeyCode.RightArrow))
transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);
}
}

如果想用碰撞体移动某个对象,也就是会产生物理作用的物体,则不应该使用上者,而是应该考虑 Physics函数

13. Look At

摄像机跟随游戏物体

CameraLookAt

1
2
3
4
5
6
7
8
9
10
11
12
using UnityEngine;
using System.Collections;

public class CameraLookAt : MonoBehaviour
{
public Transform target;

void Update ()
{
transform.LookAt(target);
}
}

14. 线性插值

在制作游戏时,有时可以在两个值之间进行线性插值。

这是通过 Lerp 函数来完成的。线性插值会在两个给定值之间找到某个百分比的值。

例如,我们可以在数字 3 和 5 之间按 50% 进行线性插值以得到数字 4。这是因为 4 是 3 和 5 之间距离的 50%。

在 Unity 中,有多个 Lerp 函数可用于不同类型。对于我们刚才使用的示例,与之等效的将是 Mathf.Lerp 函数,

如下所示:

1
2
// 在此示例中,result = 4
float result = Mathf.Lerp (3f, 5f, 0.5f);

Mathf.Lerp 函数接受 3 个 float 参数:一个 float 参数表示要进行插值的起始值,另一个 float 参数表示要进行插值的结束值,最后一个 float 参数表示要进行插值的距离。在此示例中,插值为 0.5,表示 50%。如果为 0,则函数将返回“from”值;如果为 1,则函数将返回“to”值。

Lerp 函数的其他示例包括 Color.LerpVector3.Lerp。这些函数的工作方式与 Mathf.Lerp 完全相同,但是“from”和“to”值分别为 Color 和 Vector3 类型。在每个示例中,第三个参数仍然是一个 float 参数,表示要插值的大小。这些函数的结果是找到一种颜色(两种给定颜色的某种混合)以及一个矢量(占两个给定矢量之间的百分比)。

让我们看看另一个示例:

1
2
3
4
5
Vector3 from = new Vector3 (1f, 2f, 3f);
Vector3 to = new Vector3 (5f, 6f, 7f);

// 此处 result = (4, 5, 6)
Vector3 result = Vector3.Lerp (from, to, 0.75f);

在此示例中,结果为 (4, 5, 6),因为 4 位于 1 到 5 之间的 75% 处,5 位于 2 到 6 之间的 75% 处,而 6 位于 3 到 7 之间的 75% 处。

使用 Color.Lerp时适用同样的原理。在 Color 结构中,颜色由代表红色、蓝色、绿色和 Alpha 的 4 个 float 参数表示。使用 Lerp 时,与 Mathf.LerpVector3.Lerp 一样,这些 float 数值将进行插值。

在某些情况下,可使用 Lerp 函数使值随时间平滑。

请考虑以下代码段:

1
2
3
4
void Update ()
{
light.intensity = Mathf.Lerp(light.intensity, 8f, 0.5f);
}

如果光的强度从 0 开始,则在第一次更新后,其值将设置为 4。下一帧会将其设置为 6,然后设置为 7,再然后设置为 7.5,依此类推。因此,经过几帧后,光强度将趋向于 8,但随着接近目标,其变化速率将减慢。请注意,这是在若干个帧的过程中发生的。如果我们不希望与帧率有关,

则可以使用以下代码:

1
2
3
4
void Update ()
{
light.intensity = Mathf.Lerp(light.intensity, 8f, 0.5f * Time.deltaTime);
}

这意味着强度变化将按每秒而不是每帧发生。

请注意,在对值进行平滑时,通常情况下最好使用 SmoothDamp 函数。仅当您确定想要的效果时,才应使用 Lerp 进行平滑。

C#初级编程 | Unity 中文课堂 (u3d.cn)

15.Destroy

DestroyBasic

挂载在本身

1
2
3
4
5
6
7
8
9
10
11
12
13
using UnityEngine;
using System.Collections;

public class DestroyBasic : MonoBehaviour
{
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(gameObject);
}
}
}

DestroyOther

让其他组件挂载在一个挂载这个脚本的组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using UnityEngine;
using System.Collections;

public class DestroyOther : MonoBehaviour
{
public GameObject other;


void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(other);
}
}
}

DestroyComponent

处理纹理,删掉相关渲染纹理~物体还在,纹理没了,应该相当于删掉了

1
2
3
4
5
6
7
8
9
10
11
12
13
using UnityEngine;
using System.Collections;

public class DestroyComponent : MonoBehaviour
{
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(GetComponent<MeshRenderer>());
}
}
}

16.GetButton 和 GetKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   bool down = Input.GetKeyDown(KeyCode.Space);
bool held = Input.GetKey(KeyCode.Space);
bool up = Input.GetKeyUp(KeyCode.Space);
//按下时->按住了
down = true
held = true
up = false
//->松开了,的一瞬间
down = false
held = false
up = true
//松开—>全部
down = false
held = false
up = false

KeyInput

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using UnityEngine;
using System.Collections;

public class KeyInput : MonoBehaviour
{
public GUITexture graphic;
public Texture2D standard;
public Texture2D downgfx;
public Texture2D upgfx;
public Texture2D heldgfx;

void Start()
{
graphic.texture = standard;
}

void Update ()
{
bool down = Input.GetKeyDown(KeyCode.Space);
bool held = Input.GetKey(KeyCode.Space);
bool up = Input.GetKeyUp(KeyCode.Space);

if(down)
{
graphic.texture = downgfx;
}
else if(held)
{
graphic.texture = heldgfx;
}
else if(up)
{
graphic.texture = upgfx;
}
else
{
graphic.texture = standard;
}

guiText.text = " " + down + "\n " + held + "\n " + up;
}
}

ButtonInput

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using UnityEngine;
using System.Collections;

public class ButtonInput : MonoBehaviour
{
public GUITexture graphic;
public Texture2D standard;
public Texture2D downgfx;
public Texture2D upgfx;
public Texture2D heldgfx;

void Start()
{
graphic.texture = standard;
}

void Update ()
{
bool down = Input.GetButtonDown("Jump");
bool held = Input.GetButton("Jump");
bool up = Input.GetButtonUp("Jump");

if(down)
{
graphic.texture = downgfx;
}
else if(held)
{
graphic.texture = heldgfx;
}
else if(up)
{
graphic.texture = upgfx;
}
else
{
graphic.texture = standard;
}

guiText.text = " " + down + "\n " + held + "\n " + up;
}
}

17.GetAxis

返回的是浮点数

Gravity影响按钮松开后归零的速度,越大,归零越快

Dead这个值越大,按按钮的动作就要越猛,可能

Sensitivity控制按下时,Axis达到1或-1的速度,与 Gravity相反

Snap同时按下正负按钮时,归零

AxisExample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using UnityEngine;
using System.Collections;

public class AxisExample : MonoBehaviour
{
public float range;
public GUIText textOutput;


void Update ()
{
float h = Input.GetAxis("Horizontal");
float xPos = h * range;

transform.position = new Vector3(xPos, 2f, 0);
textOutput.text = "Value Returned: "+h.ToString("F2");
}
}

AxisRawExample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using UnityEngine;
using System.Collections;

public class AxisRawExample : MonoBehaviour
{
public float range;
public GUIText textOutput;


void Update ()
{
float h = Input.GetAxisRaw("Horizontal");
float xPos = h * range;

transform.position = new Vector3(xPos, 2f, 0);
textOutput.text = "Value Returned: "+h.ToString("F2");
}
}

DualAxisExample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using UnityEngine;
using System.Collections;

public class DualAxisExample : MonoBehaviour
{
public float range;
public GUIText textOutput;


void Update ()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
float xPos = h * range;
float yPos = v * range;

transform.position = new Vector3(xPos, yPos, 0);
textOutput.text = "Horizontal Value Returned: "+h.ToString("F2")+"\nVertical Value Returned: "+v.ToString("F2");
}
}