unity学习笔记

一、获取组件的方法

1.GetComponent<>()

从当前游戏物体获取到对应组件 比如rb=GetComponent<Rigidbody2D>()

2.GetComponents<>()

返回值是一个数组,也就是当一个游戏对象上有多个同类型组件,且要获取所有同类型组件使用

二、获取物体的方法

1.GameObject.Find()

通过物体名称获取物体。 弊端:a.无法找到未被激活的对象

b.需要遍历场景中所有的物体

2.GameObject.FindGameObjectWithTag()

通过标签查找物体,返回游戏对象

3.父子关系获取物体对象

transform.Find("子物体名字”)寻找子物体 transform.GetChild()通过序号查找子物体

总结

获取游戏对象和组件方法其实有很多,上面的方法也只是列举的比较常用的,在获取物体时,脚本在物体上时--直接用GameObject就能获取,脚本不在物体上--用public公共变量获取;在获取组件时,脚本(其实脚本也算是组件)如果和组件在同一个对象上--用gameobject.GetComponent;如果脚本和组件不在同一个对象上--用public公共变量获取

三、三个提高效率的函数:GetComponent(), FindObjectByType() and Instantiate()

1、FindObjectByType()

通过这个可以将含有这个脚本的所有游戏对象都找出来放到一个数组里面去,适合需要管理多个相同或相近的游戏物体 例子:

public Bird[] birdList;
birdList = FindObjectsByType<Bird>(FindObjectsSortMode.None);

2、Instance()

单例模式 能让这个脚本在全局都能访问到。 例子:

//GameManager.cs
public static Slingshot Instance { get; private set; }
private void Awake()
{
    Instance = this;
}
//Bird.cs
rb.velocity = (Slingshot.Instance.getCenterPosition() - transform.position).normalized * flySpeed;

Invoke,用来延时调用函数

比如Invoke("LoadNextBird()",1f)意思是一秒之后调用LoadNextBird()方法 Invoke()不接受含有参数的方法 InvokeRepeating("LoadNextBird()",1f,2f)意思是1秒后调用该函数,并且之后每隔三秒调用一次该函数

GameObject.Instantiate()

是什么:用来克隆生成一个预制体对象的方法 怎么用:进行实例化的函数GameObject.Instantiate(对象(object),位置(position),旋转坐标(Quaternion))------不旋转就用Quaternion.identity 把想要实例化的对象放到Resources目录里面去 例子:GameObject.Instantiate(Resources.Load("Boom1"), transform.position, Quaternion.identity);

Q:什么时候创建manage脚本?

A:在场景中是唯一的或是公共的东西 Q:什么时候创建父类? A:几个物体有相同的属性或行为

单例模式

public static ScoreManage instance {  get; private set; }//单例模式,使其可以全局访问
private void Awake()
{
    instance= this;
}

unity中GameObject和gameObject的区别??

1.gameObject 是 Component 类的一个属性,用于获取当前组件所绑定的游戏对象 (GameObject)

void Start() { // 获取当前脚本所依附的游戏对象 GameObject obj = gameObject; // ... }

2.GameObject 则是 Unity 中表示游戏对象的类型。

游戏对象是场景中的元素,可以添加组件 (Components),用于控制其行为和外观。

// 创建一个新的游戏对象 GameObject newObj = new GameObject("New Object"); // 找到指定名称的游戏对象 GameObject obj = GameObject.Find("Object"); // 删除指定的游戏对象 Destroy(obj);

音频播放

AudioSource.PlayClipAtPoint(birdCollision, position, 1f); 在position位置播放birdCollision音频剪辑,音量大小为1f AudioSource.PlayClipAtPoint是静态方法,直接用就可以

Button组件

把想要执行的事件直接拖到Button下面就行。 比如要设置点击后执行某个函数,就把这个函数所在脚本所在对象拖到BUtton组件下面,然后选择那个脚本下面对应的函数就可以啦

如何让暂停UI出来的时候鼠标不能控制游戏物体?

EventSystem.current.IsPointerOverGameObject()这个函数用来判断鼠标是否点在了UI上,加上当EventSystem.current.IsPointerOverGameObject()==false时才能执行相关操作就行

如何让暂停时游戏也不动?

让Time.timeScale =0就可以,但是有个问题,这个时候UI动画可能也被暂停了,如何解决呢?这时应该吧Animator组件的更新模式选择为“未缩放的时间”,这样动画的播放不会受Time.timeScale影响

如何保存游戏数据?

继承ScriptObject,类型开头加上[CreateAssetMenu],就会变成一个本地存储的对象,然后通过代码控制改变游戏存储数据 ScriptObject不支持二维数组

如何加载下一个场景?

SceneManager.GetActiveScene().buildIndex是当前场景 SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);作用是加载当前场景索引值加一的场景,也就是下一个场景。场景的顺序在BuildingSetting里面改

如何遍历对应transform下所有子物体

foreach(Transform child in levelChoose.transform)
{
Destory(chid.gameObject);//删除levelChoose下的所有子物体
}

关于音乐播放的函数:

if(gameObject.GetComponent<AudioSource>().isPlaying)//如果音乐正在播放
{
    gameObject.GetComponent<AudioSource>().Pause();//那么就暂停音乐
    StopMusic.SetActive(true);//并且把禁止图标显示出来
}
else
{
    gameObject.GetComponent<AudioSource>().UnPause();//如果没播放,就继续播放音乐
    StopMusic.SetActive(false);//并且把禁止图标隐去
}

人物移动

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
​
public class PlayerControl : MonoBehaviour
{
    private Rigidbody2D rb;
​
    public float moveSpeed = 1.0f;
​
    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
    }
​
    private void Move()
    {
        float InputSpeedX = Input.GetAxis("Horizontal");//"Horizontal"是Unity内置的输入管理系统中定义的一个轴名称,用于代表水平方向的输入。
        rb.velocity = new Vector2(InputSpeedX * moveSpeed, rb.velocity.y);
    }
    private void FixedUpdate()
    {
        Move();
    }
}
​

当玩家通过键盘的左右箭头键或者A/D键,或者游戏手柄的左摇杆左右移动时,Input.GetAxis("Horizontal")会返回一个-1到1之间的浮点数。具体来说:

  • 当玩家向左移动时(如按下左箭头键或A键),该函数会返回一个小于0的值,最大为-1。

  • 当玩家向右移动时(如按下右箭头键或D键),该函数会返回一个大于0的值,最大为1。

  • 如果没有输入,即玩家没有按左右键或者摇杆处于中立位置,该函数会返回0。

人物跳跃

      ```c#  
      rb.AddForce(transform.up*jumpForce,ForceMode2D.Impulse); 
      ```
  1. AddForce(): 这是Rigidbody 2D组件的一个方法,用于给游戏对象添加力。这个方法可以接受两个参数:力的向量以及力的模式。

  2. transform.up: 这是Unity中的一个属性,代表游戏对象的上方方向。因为游戏对象可能在不同的角度,transform.up会确保力始终是垂直向上的,无论游戏对象当前的方向如何。

  3. *jumpForce: 这里是一个乘法操作,用于将transform.up(一个单位向量)乘以jumpForce(一个力的大小),得到最终的跳跃力向量。jumpForce通常是一个在脚本中定义的变量,代表跳跃时施加的力的大小。

  4. ForceMode2D.Impulse: 这是一个枚举值,用于指定力的模式。ForceMode2D.Impulse模式意味着施加的力会立即改变游戏对象的速度,而不是逐渐加速。这对于模拟跳跃或爆炸等瞬间冲击力是很有用的。

综合来看,这行代码的作用是:在Unity的2D物理环境中,给游戏对象施加一个向上的、瞬间的作用力,使其

完整代码:

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using static Unity.VisualScripting.Member;
​
public class PlayerControl : MonoBehaviour
{
    private Rigidbody2D rb;
   
    public bool is_OnGround=false;
​
    public float moveSpeed = 8.0f;
    public float jumpForce = 5f;
​
    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
    }
​
    private void Jump()
    {
        if(is_OnGround&& Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("jump!");
            rb.AddForce(transform.up * jumpForce, ForceMode2D.Impulse);
        }
    }
​
    private void Move()
    {
        Jump();
        float InputSpeedX = Input.GetAxisRaw("Horizontal");//"Horizontal"是Unity内置的输入管理系统中定义的一个轴名称,用于代表水平方向的输入。
        rb.velocity = new Vector2(InputSpeedX * moveSpeed, rb.velocity.y);
    }
    /*private void FixedUpdate()
    { 
        Move();   
    }*/
    private void Update()
    {
        Move();
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("space");
        }
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag=="Ground")
        {
            is_OnGround = true;
        }
    }
    private void OnCollisionExit2D(Collision2D collision)
    {
        if(collision.gameObject.tag=="Ground")
        {
            is_OnGround = false;
        }
    }
}
​

[SerializeField]属性

 [SerializeField] private int currentLine;

[SerializeField]是一个属性,用于在Unity编辑器中序列化一个私有字段,即使这个字段是私有的。这意味着你可以从Unity编辑器中直接看到和编辑这个字段,而不需要为它创建一个专门的getter或setter方法。

private int currentLine; 是一个私有整数变量,用于存储当前的行号或类似的值。由于它是私有的,如果没有[SerializeField]属性,这个变量在Unity编辑器中是不可见的,也无法直接编辑。

[SerializeField]private int currentLine;一起使用,可以在保持代码封装的同时,允许开发者在Unity编辑器中查看和修改currentLine的值,这在调试或设计游戏时非常有用。

快捷键

ctrl+shift+M 可以搜索方法

检查文本中是否以某标记开头

if (dialogueLines[currentLine].StartsWith("n-"))

在原字符串中查找指定的字符或字符串,并将其替换为新的字符或字符串

nameText.text = dialogueLines[currentLine].Replace("n-","");

比如英语语法中replace A with B,用B来替换A

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值