首页 > 编程语言 >Unity 游戏开发、03 基础篇 | C#初级编程

Unity 游戏开发、03 基础篇 | C#初级编程

时间:2023-09-14 22:46:58浏览次数:37  
标签:03 Direction float C# void Vector3 Unity 节点 dir

C#初级编程

https://learn.u3d.cn/tutorial/beginner-gameplay-scripting

8 Update 和 FixedUpdate

Update(不是按固定时间调用的) 经常用于

  • 移动非物理特性的物体(不是物理对象)
  • 简单定时器
  • 接收输入

FixedUpdate(调用时间间隔相同)

  • 进行任何必要的物理计算(任何物理对象)
    • 最好使用力来定义移动

使用 IDE 的 Unity Event Functions 插入函数


9 点积、叉积

image-20230914192214954

点积算出标量如果点积为 0 则两个向量互相垂直,飞机模拟例子:

  • 点积 = 0,飞机前向 Z 轴 与 Y 轴垂直,此时阻力最小
  • 点积 > 0,飞机在爬升,此时阻力变大
  • 点积 < 0,飞机在俯冲

image-20230914192741074 image-20230914192825341 image-20230914193015463

叉积算出新向量。使用左手坐标系根据 A 、B 确定 C 的方向(中指)

  • 为了确定围绕哪个轴施加扭矩 来转动坦克炮塔
  • 如果知道炮塔目前朝向目标朝向,则可以用叉积算出需要围绕的轴的方向
image-20230914193323362

10 启用和禁用组件

private Light myLight;

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

private void Update()
{
    if (Input.GetKeyUp(KeyCode.Space))
        myLight.enabled = !myLight.enabled;
}

11 激活游戏对象

  • 父节点无效后,子节点也会一同跟着无效,(不活跃节点在层次结构中依旧可见)
    • 利用父节点保持对对象群的控制
    • 子节点由于父节点被禁用而禁用时,只针对子节点setActive不管用,想要重新激活子节点就必须重新激活父节点
  • 要确认某个节点是否为活跃状态
    • activeSelf 看节点本身
    • activeInHierarchy 看父子关系(父节点关则false;根节点自身为父节点)
Debug.Log(myObject.activeSelf);
Debug.Log(myObject.activeInHierarchy);
image-20230914200507451

12 物体移动

  • 默认移动,旋转都是 Space.self
  • 移动一个有碰撞体的对象(带物理效果的物体),不能用 Translate 与 Rotate
public void Rotate(Vector3 axis, float angle) => this.Rotate(axis, angle, Space.Self);

13 LookAt

让摄像机看向某一物体

public Transform target;
private void Update()
{
    transform.LookAt(target);
}

14 Lerp

线性插值会在两个给定值之间找到某个百分比的值。

float result = Mathf.Lerp (3f, 5f, 0.5f);
// Color.Lerp 和 Vector3.Lerp

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);

在对值进行平滑时,通常情况下最好使用 SmoothDamp 函数。想要实现特定效果时,才应使用 Lerp 进行平滑。

Unity - Scripting API: Mathf.SmoothDamp (unity3d.com)

Need help understanding the Mathf.SmoothDamp function - Unity Forum

ref velocity 存在的必要性

如果目标距离较远,函数会尝试加速你的位置,如果目标越来越近,则会减速。为了加速/减速,你需要知道你的速度有多快,这就是速度参数


16 GetButton、GetKey

  • GetKey 需要使用 KeyCode 类型参数
  • KeyCode 只与特定键相关,建议使用 GetButton
    • 参数是字符串,可以在 Project Settings | Input Manager 中设置,灵活性很大
  • 两种方式都有三种状态:Down、状态、Up
private void Update()
{
    if(Input.GetButtonDown("Jump"))
        Debug.Log("按下了空格键");
    if(Input.GetButtonDown("Fire1"))
        Debug.Log("按下了鼠标左键");
}

17 GetAxis、GetAxisRaw

  • GetButton、GetKey 只返回布尔值
  • GetAxis 返回浮点值,介于-1到1之间
  • GetAxisRaw  返回浮点值,仅返回 -1,0,1,不受平滑过滤参数影响
    • 针对需要严格控制输入的2D游戏非常有用
image-20230914205224260
  • Gravity 按钮松开后归零的速度(越高归零越快)
  • Sensitivity 按钮按下后到达1或-1的速度有多快(越高越快)
  • Dead 值针对手柄盲区(LS、RS轻微转动不影响)(越大盲区越大)
private void Update()
{
    float x = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");
    float x2 = Input.GetAxisRaw("Horizontal");
    float v2 = Input.GetAxisRaw("Vertical");
    Debug.Log($"{x} {v} {x2} {v2}");
}

void Movement ()
{
    float forwardMovement = Input.GetAxis("Vertical") * speed * Time.deltaTime;
    float turnMovement = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;

    transform.Translate(Vector3.forward * forwardMovement);
    transform.Rotate(Vector3.up * turnMovement);
}

18 onm ouseDown

用于检测对 带碰撞体组件的物体节点GUI元素 鼠标点击事件

以下代码针对一个物理物体,每次鼠标点击给予 forward 反方向的推力

private void onm ouseDown()
{
    Debug.Log($"点击 {gameObject.name}");
    rb.AddForce(-transform.forward * 500f);
}

19 GetComponent

GetComponent 性能消耗大,应该尽量减少调用,最好是在 Awake,Start 调用


20 deltaTime

定时器功能与平滑移动(按速度移动)

public float speed = 8f; 
public float countdown = 3.0f;

void Update ()
{
    countdown -= Time.deltaTime;
    if(countdown <= 0.0f)
        light.enabled = true;

     if(Input.GetKey(KeyCode.RightArrow))
        transform.position += new Vector3(speed * Time.deltaTime, 0.0f, 0.0f);
}   

21 值、引用

image-20230914213217303

  • 值类型对应的值被改变,只会影响特定变量
  • 引用类型指向的值被改变,所有包含相同存储地址的引用类型变量都会受到影响
    void Start () 
    {
        //值类型变量
        Vector3 pos = transform.position;  // 值拷贝
        pos = new Vector3(0, 2, 0); 
        
        //引用类型变量
        Transform tran = transform;
        tran.position = new Vector3(0, 2, 0);
    }

22 类

  • 拆分类的功能,不要全部写在一起(单一职责原则)
    • 如射击类、移动类、库存类
  • 多用代码段,比如 ctor 生成构造函数
  • 先全面仔细设计脚本结构,再开始编写一个大类,将各种不同内容囊括其中

23 Instantiate

Instantiate 用于动态生成预制体对象(创建预制件的克隆体)

动态实例化生成的子弹预制体节点被强制转型成了 RigidBody

public Rigidbody bulletPrefab; // 可以不是GameObject而是绑定的组件
public Transform firePosition;
public float bulletSpeed;   
...
Rigidbody bulletInstance = Instantiate(bulletPrefab, firePosition.position, firePosition.rotation) as Rigidbody;

案例中用到了 as 关键字。《C# 8.0本质论》里没有写

  • 按(Rigidbody)显示转换方式如果转换不成功会抛出异常
  • as 运算符类似于强制转换操作;但是,如果转换不可行,as 会返回 null 而不是引发异常

24 数组

使用 FindGameObjectsWithTag 初始化查找所有 Tag 为 Player 的节点存储至数组中

C# 数组是从抽象的基类型Array派生的引用类型

public GameObject[] players;

void Start()
{
    players = GameObject.FindGameObjectsWithTag("Player");
    foreach (var player in players)   
    {
        Debug.Log($"{player.name}");
    }
}

25 Invoke

  • Invoke 调用的函数必须 不包含参数,且无返回值

其他内容以前笔记有写,略过


26 enum

用整数描述方向不易读,可以建立 enum 类型(类内类外都可创建

enum Direction : short
{
    North, // 0 
    East,  // 1
    South = 100, // 100
    West   // 101
};
void Start()
{
    Direction myDirection;
    myDirection = Direction.North;
    var newDirection = ReverseDirection(myDirection);
}

Direction ReverseDirection (Direction dir)
{
    if(dir == Direction.North)
        dir = Direction.South;
    else if(dir == Direction.South)
        dir = Direction.North;
    else if(dir == Direction.East)
        dir = Direction.West;
    else if(dir == Direction.West)
        dir = Direction.East;

    return dir;     
}

27 switch

跟 C++ 差不多

public int intelligence = 5;
void Start()
{
    switch (intelligence)
    {
        case 1:
            break;
        case 2:
            break;
        default:
            break;
    }
}

标签:03,Direction,float,C#,void,Vector3,Unity,节点,dir
From: https://www.cnblogs.com/linxiaoxu/p/17703722.html

相关文章

  • CSP-J&S 2023 游记
    本游记中的时间均表示为日期(初赛基准时间/复赛基准时间)2023-9-14(-1/-36)创建了这篇游记。开始准备初赛,做了几份真题(\(CSP-S2015\),\(CSP-S2021\),\(CSP-S2022\)),但感觉没啥用,近几年的都做过,远古的又太简单。几乎没复习基础知识,感觉有点慌。......
  • PivotGridControl自定义行数据的统计公式
    我们在使用PivotGridControl进行数据统计的时候,用时候需要在不同的行使用不同的汇总公式的情况,本文就是为了说明怎么实现此功能,如下图说明 数据源: 注意:此时数据列指定的SummaryType设置的是Sum;并且数据列指定了为double类型  SummaryType指定的几种聚合函数,Max、Min、......
  • C++下标运算符详解
    C++规定,下标运算符[]必须以成员函数的形式进行重载。该重载函数在类中的声明格式如下:返回值类型&operator[](参数);const返回值类型&operator[](参数)const;使用第一种声明方式,[]不仅可以访问元素,还可以修改元素。使用第二种声明方式,[]只能访问而不能修改元素。在实......
  • pytorch(1) 学习资料
    https://tangshusen.me/Dive-into-DL-PyTorch/#/chapter03_DL-basics/3.1_linear-regression  https://pytorch.zhangxiann.com/1-ji-ben-gai-nian/1.2-tensor-zhang-liang-jie-shao  https://datawhalechina.github.io/thorough-pytorch/%E7%AC%AC%E4%B8%83%E7%AB%A0/7......
  • 解决使用【git check】切换分支命令时出现error的错误!
    问题:PSD:\PycharmProject(D)\Baidu-Image-Loader>gitcheckoutmastererror:Thefollowinguntrackedworkingtreefileswouldbeoverwrittenbycheckout:.idea/.gitignore.idea/Baidu-image-loader.iml.idea/deployment.xml......
  • uniapp-net core后台-实现认证
    一在program.cs中添加cookie认证builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options=>{options.Cookie.Name="auth";options.ExpireTimeSpan=TimeSpan.FromDays(1);options.Sli......
  • csp模拟 烦死!!!
    好久没有写博客了csp模拟38我是A题真是服了,好好一个题怎么恶心的时间空间,自家oj的评测机真是欠修理。考虑\(z\)从大到小时计算每层的剩下的值,割去的一定是一个阶梯状的图形,考虑到每一层,新增加的就是两条线割剩下的,且这两条线从上到下递增,维护前缀和计算就可以。点击查看代......
  • 分享一个自定义颜色的侧边栏CSS
    很简单!将以下代码放入站点的css即可生效,css中的颜色可自定义修改RGB/HEX的颜色值~/**彩色滚动条样式开始*/::-webkit-scrollbar{width:10px;height:1px;}::-webkit-scrollbar-thumb{background-color:#a0c595;background-image:-webkit-linear-gradient(45......
  • 20230914-python爬取数据写入到excel
    python爬取数据写入到excel1。查看是否安装了相应的插件 piplist2。查看是否安装了  pandas     (安装命令在cmd中安装,pipinstallpandas)3。查看是否安装 openpyxl      pipinstallopenpyxl ####写入excelimportpandasaspddf=pd.DataFra......
  • spring-ioc容器
    不需要自己创建IOC容器对象任何需要的bean都可以在测试类中直接享受自动装配首先导入依赖<!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.3.1</version></depend......