//using命名空间,类比java的import包
using 命名空间;
public class 类名: MonoBehaviour
{
void 方法名();
Debug.Log("调试显示信息");
print("本质就是Debug.Log方法");
}
鼠标右键创建即可,选择C# script
在unity中创建出的C#脚本文件模板内部的构造:
using UnityEngine;
using System.Collections;
public class demo01 : MonoBehaviour {
// 默认会带两个方法,如果不使用请删除
// Use this for initialization
void Start () {
}
// Update is called once per frame
// Update方法不用的话就把它删除,因为此方法会被不断的调用,大概0.02s被调用一次
void Update () {
}
}
模板也是可以自定义的,我们到unity的目录下:
修改为:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
///
///
public class #SCRIPTNAME# : MonoBehaviour
{
}
public class NewBehaviourScript : MonoBehaviour
{
//public类型默认会在Insepctor中显示
public int A;
//private类型默认不会在Insepctor中显示
private string B = "abc";
//[SerializeField]
//作用:在Unity编译器中显示当前private的字段
[SerializeField]
private bool C = true;
//[Range(1,100)]
//作用:在Unity编译器中限定此字段的值为0~100
[Range(1, 100)]
public int D = 10;
//[HideInInspector]
//作用:在Unity编译器中隐藏当前public的字段
[HideInInspector]
public float E = 1.0f;
}
///
/// 脚本生命周期
///
public class LIfeCycle : MonoBehaviour
{
//执行时机:创建游戏对象时,立即执行1次 (与脚本禁用与否无关)
//作用:初始化
private void Awake()
{
Debug.Log("Awake()方法被调用了!");
}
//执行时机:每当脚本对象启用时调用,执行1次
//作用:初始化
private void OnEnable()
{
Debug.Log("OnEnable()方法被调用了!");
}
//执行时机:创建游戏对象时,且脚本未被禁用时,执行1次
//作用:初始化
private void Start()
{
Debug.Log("Start()方法被调用了!");
}
}
将脚本挂到游戏对象上,测试一下
需要碰撞器Collider,即unity中的这些collider:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// 脚本生命周期
///
public class LIfeCycle : MonoBehaviour
{
//===================初始阶段===================
//执行时机:创建游戏对象时,立即执行1次 (与脚本禁用与否无关)
//作用:初始化
private void Awake()
{
Debug.Log("Awake()方法被调用了!");
}
//执行时机:每当脚本对象启用时调用,执行1次
//作用:初始化
private void OnEnable()
{
Debug.Log("OnEnable()方法被调用了!");
}
//执行时机:创建游戏对象时,且脚本未被禁用时,执行1次
//作用:初始化
private void Start()
{
Debug.Log("Start()方法被调用了!");
}
//===================物理阶段===================
//执行时机:每隔固定时间被调用,默认为0.02s(时间可以更改)
//适用性:适合对物体做物理操作(移动,旋转等),不会受到渲染的影响。
//因为每帧渲染物体量不固定机器性能不同,进而渲染的时间是不固定。
//总之记住不管怎么样FixedUpdate()每隔0.02s执行一次就行
private void FixedUpdate()
{
Debug.Log("FixedUpdate()方法被调用了!");
}
//===================游戏逻辑阶段===================
//执行时机:每渲染一帧执行一次(联系FixedUpdate()对应理解),渲染受到机器性能个每帧渲染量影响,执行间隔时间不确定
//适用性:处理游戏逻辑,但是现在大部分移动也是写这儿
private void Update()
{
Debug.Log("Update()方法被调用了!");
}
}
具体就是脚本的一些函数执行流程:
MonoDevelop:Unity:Unity自带脚本编辑器,创建Mono应用程序,适用于Linux、Mac OS X和Windows的集成开发环境,支援C#、BOO和JavaScript等高级编程语言。
微软公司的开发工具包,包括了整个软件生命周期中需要的大部分工具,如团队开发工具、集成开发环境等等。
注意看图中的MonoBehaviour,一般我们是继承MonoBehaviour来编写脚本
主要是获取游戏对象的组件,改变组件相关数值
主要是使用GetComponent()方法获取组件,然后在对组件的属性进行操作
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// Component类提供了查找(在物体、后代、先辈)组件的功能
///
public class ComponentDemo : MonoBehaviour
{
//OnGUI()基本不使用,这里用于测试功能,会在运行时在屏幕上添加按钮
private void OnGUI()
{
if (GUILayout.Button("修改位置"))
{
//改变当前游戏对象的位置,修改transform的position属性
this.transform.position = new Vector3(0, 0, 10);
}
if (GUILayout.Button("修改BoxCollider大小"))
{
//获取游戏对象里边BoxCollider类型的组件,并将其size属性设置为1, 2, 3
this.GetComponent<BoxCollider>().size = new Vector3(1, 2, 3);
}
if (GUILayout.Button("GetComponents"))
{
//获取游戏对象里边Component类型的组件
var allComponents = this.GetComponents<Component>();
//遍历出我们找到的组件
foreach(var item in allComponents)
{
print("获取到的组件为:" + item.GetType());
}
}
}
}
if (GUILayout.Button("GetComponentsInChildren"))
{
//获取当前游戏对象后代物体的里边MeshRenderer类型的组件(从自身开始找起,包括自己)
var allComponents = this.GetComponentsInChildren<MeshRenderer>();
//遍历出我们找到的组件
foreach (var item in allComponents)
{
print("获取到后代的组件为:" + item.GetType());
}
}
if (GUILayout.Button("GetComponentsInParent"))
{
//获取当前游戏对象先辈物体的里边MeshRenderer类型的组件(从自身开始找起,包括自己)
var allComponents = this.GetComponentsInParent<MeshRenderer>();
//遍历出我们找到的组件
foreach (var item in allComponents)
{
print("获取到后代的组件为:" + item.GetType());
}
}
主要是设置游戏对象物体的旋转缩放位置等等,可以制作游戏移动之类的操作
if (GUILayout.Button("foreach-transform"))
{
foreach (Transform child in this.transform)
{
//遍历出当前对象每个子物体的变换组件,孙子类就不行了
print("获取到子物体的变换组件为:" + child.name);
//物体相对与世界坐标系的位置
//this.transform.position;
//物体相对于父物体轴心点
//this.transform.localPosition;
//相对与父物体的缩放比例 1 2 1(xyz轴比例)
//this.transform.localScale;
//this.transform.lossyScale
//如:父物体localScale为3当前物体localScale为2
//lossyScale则为6
//理解为:物体与模型缩放比例(自身缩放比例*父物体缩放比例)
//this.transform.lossyScale
//如:父物体localScale为3当前物体localScale为2
//lossyScale则为6
}
}
if (GUILayout.Button("z轴移动1m"))
{
//向自身坐标系z轴,移动1m
this.transform.Translate(0, 0, 1);
}
if (GUILayout.Button("y轴旋转1m"))
{
//沿着自身坐标系y轴旋转10度
this.transform.Rotate(0, 10, 0);
//沿着世界坐标系y轴旋转10度
this.transform.Rotate(0, 10, 0, Space.World);
}
public class ComponentDemo : MonoBehaviour
{
//传入一个物体的变换组件的引用,使得我们可以对其操作
public Transform tf;
private void OnGUI()
{
if (GUILayout.Button("GetParent-Transform"))
{
//获取父物体的变换组件
Transform parentTF =this.transform.parent;
}
if (GUILayout.Button("SetParent-true"))
{
//将传入的Transform设置当前对象的父物体
//true:当前物体的位置视为世界坐标,参照物为世界坐标
this.transform.SetParent(tf, true);
}
if (GUILayout.Button("SetParent-false"))
{
//将传入的Transform设置当前对象的父物体
//false:当前物体的位置视为localPosition,参照物为父物体轴心点
this.transform.SetParent(tf, false);
}
}
}
SetParent-true
按钮,然后改变cube(6)的位置,发现cube和cube(6)做相对运动(其实这就是正常的子物体与父物体关系)。类比载具,相当于cube上了名为cube(6)的车。cube就跟着父物体cube(6)一起走了。SetParent-false
按钮,会发现cube的坐标会直接变为cube(6)的坐标(即重叠了),然后拖动cube(6),发现cube不会再移动。查看cube的坐标为(0,0,0),查看cube(6)的坐标为(0,2,0),所以就是cube将cube(6)的位置作为了参照物而已SetParent-true
就是正常的父物体与子物体的关系,子物体跟着父物体移动,无需记忆;SetParent-false
则是将子物体的Transform的参照点改变了,原本物体创建都是默认将世界坐标作为参照点,这里是直接将父物体的坐标设置为了参照点而已。if (GUILayout.Button("FindChildTransform"))
{
//根据名称寻找子物体的Transform
Transform childTF=this.transform.Find("cube(1)");
//根据索引寻找子物体的Transform
//Transform childTF = this.transform.GetChild(0);
}
public class GameObjectDemo : MonoBehaviour
{
private void OnGUI()
{
//获取在场景中物体激活状态(物体实际激活状态)
//this.gameObject.activeInHierarchy
//获取物体激活状态,激活也有可能不显示。例如:父物体取消激活,子物体就算激活了也显示不出来
//this.gameObject.activeSelf
//设置物体的激活状态
//this.gameObject.SetActive()
}
}
public class GameObjectDemo : MonoBehaviour
{
private void OnGUI()
{
if (GUILayout.Button("添加光源组件"))
{
//创建物体
GameObject lightGo = new GameObject();
//添加组件
Light light=lightGo.AddComponent<Light>();
//设置光的颜色
light.color=Color.red;
//设置光的类型
light.type = LightType.Point;
}
}
}
下:
public class GameObjectDemo : MonoBehaviour
{
private void OnGUI()
{
if (GUILayout.Button("添加光源组件"))
{
//创建物体
GameObject lightGo = new GameObject();
//添加组件
Light light=lightGo.AddComponent<Light>();
//设置光的颜色
light.color=Color.red;
//设置光的类型
light.type = LightType.Point;
}
}
}
Enemy
的脚本public class Enemy : MonoBehaviour
{
//血量
public float HP;
}
FindEnemyDemo
的脚本public class FindEnemyDemo : MonoBehaviour
{
private void OnGUI()
{
if (GUILayout.Button("查找血量最低的敌人"))
{
//寻找所有含有Enemy类型的引用
Enemy[] Enemies = FindObjectsOfType<Enemy>();
//找出血量最低的游戏对象的引用
Enemy min = FindEnemyByMinHP(Enemies);
//获取血量最低的敌人的Transform组件
Transform minTransform = min.GetComponent<Transform>();
//将血量最低的敌人positon设置为3,3,3
minTransform.position = new Vector3(3, 3, 3);
}
}
public Enemy FindEnemyByMinHP(Enemy[] Enemies)
{
//假设第一个就是血量最低的敌人
Enemy min = Enemies[0];
//依次与后面比较
for (int i = 1; i < Enemies.Length; i++)
{
if (min.HP > Enemies[i].HP)
{
min = Enemies[i];
}
}
return min;
}
}
Enemy
挂到6个cube上。然后给cube中的HP赋值。这样我们就可以开始找血量最低的游戏对象了public class TransformHelper : MonoBehaviour
{
///
/// 在层级位置的情况下查找子物体
///
///
/// 子物体名称
///
public static Transform GetChild(Transform parentTF, String childName){
//在子物体中查找
Transform childTF=parentTF.Find(childName);
//找到了返回引用
if (childTF!=null){
return childTF;
}
//将问题交给子物体
int count = parentTF.childCount;
for (int i = 0; i < count; i++){
childTF = GetChild(parentTF.GetChild(0), childName);
//找到了返回引用
if (childTF!=null){
return childTF;
}
}
//以上都没找到,就返回null
return null;
}
}