草庐IT

(C#脚本)Unity中角色移动的几种实现方法,以及心得。(适合新手入门)

记阿楠同学黑历史的小册子 2023-10-30 原文

目录

1.对Unity脚本写入有一定的思维了解。

2.分析需求,观察了解要实现的项目的条件在Unity中的外在表现。

3.开始通过代码实现功能。

4.一个整体的代码实现

5.学习心得


 

 

PS:首先我们要知道,在C#中Transform组件是可以直接调用的,而其他的(例如:Rigidbody,Animator)都需要通过 GetConpoment<组件的名称>(); 来获取进行实例化(一般在初始化时)。

例子:调用Rigidbody2D

private Rigidbody2D rb2D;//声明变量实例化

void Start()

{

      rb2d = GetComponent<Rigidbody2D>();//获取

}

1.对Unity脚本写入有一定的思维了解。

我们在C#中想要实现对Unity内各个组件、属性设置的修改和调用,首先要观察它在外部的形式,也就是Unity内的表现

比如我想要控制2D角色移动,那么改变的就它在X,Y轴上的坐标(横向和竖向),可以观察到每个物体的Transform组件下的Position就是该物体的坐标位置,所以我们只需要在脚本实现修改该坐标位置即可实现物体的移动。(见图1.1)

图1.1

2.分析需求,观察了解要实现的项目的条件在Unity中的外在表现。

a.上文已经提到,移动实际上就是物体坐标的改变,其次我们需要用键盘或鼠标对它进行控制,它需要有一个移动速度。

b.在Unity的Project Setting中可以看到它内置了Inpuut Manager,它作为对外和键盘鼠标交互。Horizontal控制物体在X轴上的运动,“A,D”输入(可以直接在外部修改)Vertical控制物体Y轴上的运动。(见图2.1)

 图2.1

3.开始通过代码实现功能。

a.在Assets里新建Scripts文件夹用于存放脚本文件,在该文件夹中建立PlayerMovementController脚本。

b.需要设置的变量,移动速度moveSpeed,定义一个二维向量moveDir

using UnityEngine;

public float MoveSpeed=3.0f;
private Vector2 moveDir = new Vector2();

ps:速度用public(把它暴露出去),方便我们在外部进行修改,表现是图3.1

 图3.1

c.写移动函数

把二维向量的两个方向与键盘交互绑定,当按一下A键,X坐标就有左边的1的增量

private void MoveCharacter
{
  moveDir.x = Input.GetAxisRaw('Horizontal');
  moveDir.y =Input.GetAixisRaw('Vertical');
  moveDir.Normalize();//当有两个方向的向量时进行整合

}

ps:Normalize 作为将两个方向向量合并处理的一个函数

图3.2

(1)调用transform代码实现

ps:因为我们这个组件做好后要挂到Player上,所以这里的transform都是直接调用的Player的。

在坐标位置上加上变化值

transform.position += Vector3(moveDir.x,moveDir.y,0.0f) * MoveSpeed * Time.deltaTime;

ps:其中Time.delate相当于一个变量,理解为在一定时间内完成上一帧的动作,运行有50帧,它就是0.02,它会随着电脑运行帧率而变化,目的是为了让游戏在不同电脑环境下都显得更为流畅稳定。

调用transform自带的Translate函数直接修改变化

transform.Translate(moveDir * MoveSpeed * Time.deltaTime);

(2)调用RigidBody2D实现代码

要先给Player挂上Rigidbody2D的组件,直接在Unity界面Player下Add Component

先声明变量

private RigidBody2D rb2d;

用Rigidbody2D内置的MovePosition函数

rb2d.MovePosition(new Vector2(transform.position.x,transform.position.y)+moveDir * MoveSpeed * Time.fixedDeltaTime);

在原坐标上增加变化值

rb2d.position += moveDir * MoveSpeed * Time.fixedDeltaTime;

把Player当作一个刚体,相当于给它一个速度推动移动,调用velocity函数,它内置了fixeddDeltaTime,所以不用乘出来

rb2D.velocity = moveDir * MoveSpeed;//velocity函数相当于内置了fixedDeltaTime,所以不用乘。

以上是利用Rigidbody2D的三种实现方法,这里用的Time.fixedDeltaTime,下面说一下它的解读以及和Time.deltaTime的区别。

使用Time.fixedDeltaTime要放到FixedUpdate运行,fixedUpdate的刷新根据fixedDeltaTime的时间来的,而它是一个固定值0.02,相当于是1秒50帧。

Update是每帧调用一次。

4.一个整体的代码实现

transfo:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovementController : MonoBehaviour
{
    public float moveSpeed = 3.0f;
    private Vector2 movDir = new Vector2();
    private Rigidbody2D rb2d;

    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

     private void FixedUpdate()
    {
        MoveCharacter();
    }
    void Update()
    {
        UpdateState();
    }
    private void MoveCharacter()
    {
        movDir.x = Input.GetAxisRaw("Horizontal");
        movDir.y = Input.GetAxisRaw("Vertical");
        movDir.Normalize();
        transform.position += new Vector3(movDir.x, movDir.y,0.0f) * moveSpeed * Time.deltaTime;
 
        transform.Translate(movDir * moveSpeed * Time.deltaTime);

    }



}

Rigidbody2D :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovementController : MonoBehaviour
{
    public float moveSpeed = 3.0f;
    private Vector2 movDir = new Vector2();
    private Rigidbody2D rb2d;

    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

     private void FixedUpdate()
    {
        MoveCharacter();
    }
    void Update()
    {
        UpdateState();
    }
    private void MoveCharacter()
    {
    rb2d.MovePosition(new Vector2(transform.position.x, transform.position.y) + movDir * moveSpeed * Time.fixedDeltaTime);
        rb2d.position += movDir * moveSpeed * Time.fixedDeltaTime;
        rb2d.velocity = movDir * moveSpeed;

    }



}

5.学习心得

最后说一点,我认为Unity的学习重在实践,多跟着别人的教学项目做,但不能单纯跟着,要多思考,它这个函数背后是怎么运作的,以后自己写别的时候这点要注意什么,上手之后有了问题再去解决,实践出真知一点没错。

我个人是先看视频,再着手做,做完后,再根据自己做的东西总结成笔记,最后来写成博客,就像是努力让别人也能接收,也是对自己知识的一种升级巩固。

 

有关(C#脚本)Unity中角色移动的几种实现方法,以及心得。(适合新手入门)的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  3. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  4. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  5. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  6. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  7. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  8. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  9. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  10. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

随机推荐