文章目录

  • 学习路径
  • 第一个脚本
  • 脚本生命周期
  • Awake Start
  • Update与FixedUpdate
  • MonoBehavior事件响应函数(Message:可重写函数)

  • gameObject
  • Transform场景物体的变换
  • Transform坐标系
  • 坐标系种类
  • 坐标系转换
  • 坐标系选择
  • Position位移
  • Rotation 旋转
  • Scale缩放
  • Hierarchy 中位置关系的调整
  • Time.deltaTime


学习路径

unity 脚本添加pass unity添加脚本没有transform_unity


unity 脚本添加pass unity添加脚本没有transform_Time_02

第一个脚本

yeah,unity第一次运行脚本成功,哦耶

unity 脚本添加pass unity添加脚本没有transform_unity_03

//MonoBehaviour自带的两个方法,一个是游戏启动时触发start事件,update是每一帧触发事件
//打印有多种方法,print Debug
private void Start() {
    print("hello unity!");
    // Debug.Log("hello");
    // Debug.LogWarning("warning");
    // Debug.LogError("error");
}
private void Update() {
    Debug.LogError("error");
}
脚本生命周期

直接贴官方链接吧:
脚本生命周期流程图

Awake Start
Update与FixedUpdate
  • Update:每一帧调用一次,一般用于非物理运动
  • FixedUpdate:每隔固定时间调用以此,一般用于物理运动
    当我们的方法涉及到物理运算,例如collider、rigidBody时,都要将方法写到fixedUpdate中

fixedUpdateTime可以在unity Edit>project settings>Time设置
这里用到了一个Time.deltaTime方法记录上一次执行时间间隔

//     The interval in seconds from the last frame to the current one (Read Only).
public static float deltaTime { get; }

似乎提到物理运动*Time.deltaTime可以使物体运动更加稳定?

private void Update() { 
Debug.Log("Update:"+Time.deltaTime);
this.transform.position = new Vector3(transform.position.x,transform.position.y +0.1f*Time.deltaTime,transform.position.z);
        }
MonoBehavior事件响应函数(Message:可重写函数)

参考视频(第10分钟)

  • 启动与刷新函数
  • 启动:Reset(),Awake(),Start()
  • 刷新:FixedUpdate(),Update(),LateUpdate()
  • 交互函数
  • 物理Physic:OnTriggerEnter(),OnTriggerExit(),OnTriggerStay(),OnCollisionEnter(),OnCollisionExit(),OnCollisionStay(),OnControllerColliderHit(),OnJointBreak(),OnParticleCollision()
  • 输入Input:OnMouseOver() OnMouseEnter() OnMouseExit() OnMouseDown() OnMouseUp() OnMouseDrag() OnMouseUpAsButton()
  • 渲染Rendering:OnGUI() OnDrawGizmos() OnDrawGizmosSelected() OnPreCull() OnPreRender() OnPostRender() OnRenderObject() OnWillRenderObject() OnRenderImage()
  • 对象Object:OnEnable() OnDisable() OnDestroy()
  • 场景Scene:OnLevelWasLoaded()
  • 程序Appliction:OnApplicationPause OnApplicationFocus OnApplicationQuit
  • 网络Network:OnPlayerConnected OnServerInitialized OnConnectedToServer OnPlayerDisconnected OnDisconnectedFromServer OnFailedToConnect OnFailedToConnectToMasterServer OnMasterServerEvent OnNetworkInstantiate OnSerializeNetworkView
  • 动画Animator:OnAnimatorMove OnAnimatorIK
  • 声音Audio:OnAudioFilterRead

OnTriggerEnter(): 当 Collider(碰撞体)进入trigger(触发器)时调用

unity面板 isTriggle勾选可以忽略物理碰撞

unity 脚本添加pass unity添加脚本没有transform_学习_04


根据教程创建两个cube,可以用重力移动,也可以用帧刷新改变位置触发碰撞

unity 脚本添加pass unity添加脚本没有transform_Time_05

gameObject

哦哦 我知道up以什么思路将这些东西了,官网有这个

unity 脚本添加pass unity添加脚本没有transform_unity 脚本添加pass_06


然后我看up讲解时直接用gameobject,emm?点进去发现是unity自带的属性,百度了下是Unity帮你实例化好了,指的就是你脚本所绑定的物体,奥奥,大概了解了。

unity 脚本添加pass unity添加脚本没有transform_unity_07


参见官网Component类 (md,这个键盘打字太™舒服了)插一句,看到这么多东西要学时,难免会泄气,然后会给自己打气,自律啥的,结合昨天看到的“NLP逻辑层次模型”

unity 脚本添加pass unity添加脚本没有transform_学习_08



所以,一定要明确自己是热爱背后所蕴含的“创造”,可以是游戏、小说、图片、动画,可以是剧情、音乐、哲理,我爱的是这个,我最希望是用自己所擅长的东西去演绎去表达,一定不能忘记初心,本末倒置,加油,自己!

还有看视频容易浮躁,但不看视频又摸不到方向,加油吧~

哈哈哈哈,小有成就,大概就是给刚体加了个冲击函数~

unity 脚本添加pass unity添加脚本没有transform_学习_09


代码:

public class AddImpulseTest : MonoBehaviour {
        public Rigidbody rb;
        //todo
        private void Awake() {
            rb = gameObject.GetComponent<Rigidbody>();
            AddImpulse();
        }
    
        public void AddImpulse(){
            rb.AddForce(0,0,-10,ForceMode.Impulse);
        }
        
    }

期间遇到脚本没有更新的情况,一开始摸不着头脑,reset好像也不行,然后就删了脚本重新绑定就好了。
b站那个视频大概思路就是用gameObject获取父子层级的对象以及通过对象名查找来获取gameObject,然后分别调用addImpulse函数施加一个z轴的冲击。

GameObject obj1 = rb.GetComponentInParent<GameObject>();
GameObject obj2 = rb.GetComponentInChildren<GameObject>();
GameObject obj3 = GameObject.Find("Wall").GetComponent<GameObject>();

up提到了申明和获得实例化的顺序,也就是脚本生命周期的问题,那个东西很多,慢慢学。

Transform场景物体的变换

Transform坐标系

unity 脚本添加pass unity添加脚本没有transform_学习_10



坐标系种类

Unity 中使用到的坐标系分为以下四种

  • 世界坐标系 Word Space
  • 即世界空间使用的坐标系,基本单位 unit,x 正方向:左向右, y 正方向:下向上,z 正方向:屏外向屏内,
  • 任何物体使用 Transform.position 即可获得世界坐标值
  • 场景中根物体使用的就是世界坐标,可在 Inspector 查看世界坐标值
  • 对于非根物体则以父物体位置为原点位置使用本地坐标系 Local Space,即相对父物体位置,该物体 Inspector 数值为本地坐标值,可使用 Transform.localposition 获取本地坐标值
  • 屏幕坐标系 Screen Space
  • 基本单位像素,屏幕左下角为(0,0),右上角为(Screen.width,Screen.height),即实际运行屏幕下的游戏窗口像素值,z 为相机世界坐标单位值
  • Input.mousePosition 获取的鼠标坐标,Input.GetTouch(0).position 获取触摸坐标
  • 视口坐标系 Viewport Space
  • 左下角为(0,0),右上角为(1,1),z 为相机世界坐标单位值
  • 适合用于坐标系转换
  • UGUI 坐标系 UGUI Space
  • 基本单位像素,屏幕左上角为(0,0),右下角为(Screen.width,Screen.height)
坐标系转换
// 本地→世界    
transform.TransformPoint(position);
// 世界→本地  
transform.InverseTransformPoint(position);
// 世界→屏幕  
camera.WorldToScreenPoint(position);  
// 世界→视口  
Camera.main.WorldToViewportPoint(position)
// 屏幕→视口  
camera.ScreenToViewportPoint(position);
// 视口→屏幕  
camera.ViewportToScreenPoint(position);
// 视口→世界  
camera.ViewportToWorldPoint(position);
坐标系选择

世界坐标系 Space.World 与自身坐标系 Space.Self

Vector3.forward、Vector3.back、Vector3.left、Vector3.right、Vector3.up、Vector3.down 数值固定

transform.forward、 transform.right、transform.up 数值不定,依据物体自身旋转变化,如 transform.forward 为物体 z 轴在世界坐标系中所指方向

Position位移

unity 脚本添加pass unity添加脚本没有transform_Time_11

public GameObject cube;
    void Update()
    {
        if(Input.GetKeyDown (KeyCode.Q)){
            cube.transform.parent = transform;
            cube.transform.localPosition = Vector3.forward*4;
        }
    }

接收按键 将cube作为子项

unity 脚本添加pass unity添加脚本没有transform_unity 脚本添加pass_12


按Q键cube则在绑定到前方,有点mc那种手持物品的效果了哈哈哈

Rotation 旋转

unity 脚本添加pass unity添加脚本没有transform_unity_13


eulerAngles:相对于世界坐标系角度

localEulerAngles:相对于自身坐标系

void Update()
{
    this.transform.Rotate(0,45f*Time.deltaTime,0,Space.World);
}

嘿嘿 又小有成就了

unity 脚本添加pass unity添加脚本没有transform_Time_14


rotateAround()

public GameObject target;
    void Update()
    {
        this.transform.RotateAround(target.transform.position,Vector3.up,45f*Time.deltaTime);
    }

unity 脚本添加pass unity添加脚本没有transform_学习_15


LookAt() 做到镜头跟随 官网文档

//public void LookAt (Transform target);
//public void LookAt (Transform target, Vector3 worldUp= Vector3.up);

public GameObject target;
    void Update()
    {
    // Rotate the camera every frame so it keeps looking at the target
        this.transform.LookAt(target.transform.position);
    }

unity 脚本添加pass unity添加脚本没有transform_学习_16

Scale缩放

unity 脚本添加pass unity添加脚本没有transform_unity 脚本添加pass_17

public float scale;
    public AnimationCurve curve;
    private void Start() {
        scale = 5f;
    }
    // Update is called once per frame
    void Update()
    {
        scale = curve.Evaluate(Time.time/2f)*2f;
        transform.localScale = new Vector3(scale, scale, scale);
    }

曲线起点和终点都选择ping pong(虽然不太懂,以后能系统学习吧)

unity 脚本添加pass unity添加脚本没有transform_世界坐标_18


unity 脚本添加pass unity添加脚本没有transform_unity 脚本添加pass_19

Hierarchy 中位置关系的调整

unity 脚本添加pass unity添加脚本没有transform_unity_20

Time.deltaTime

描述:完成上一帧所用的时间(以秒为单位)(只读)。
使用该函数可以让您的游戏独立于帧率。
如果您在每一帧中添加或减去一个值,则您可能应该乘以 Time.deltaTime。 与 Time.deltaTime 相乘的基本含义是: 我需要让该对象每秒移动 10 米,而不是每帧移动 10 米。
从 MonoBehaviour 的 FixedUpdate 内部调用时, 返回固定帧率增量时间。
注意,您不应该依赖 OnGUI 内部的 Time.deltaTime, 因为每帧可以多次调用 OnGUI,并且 deltaTime 将在每次调用时保持相同的值, 直到下一帧才进行更新。

这是官网的答案,我理解下,乘以deltaTime,利用s=v*t来理解,相当于方法参数接收的是移动距离,方法放在update()中就相当于每帧移动的距离,这个值会随着deltaTime不同存在差距,所以能让游戏独立于帧率。(大概这么理解吧)