RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 931703
Accepted
Artik Slayer
Artik Slayer
Asked:2020-01-14 01:33:59 +0000 UTC2020-01-14 01:33:59 +0000 UTC 2020-01-14 01:33:59 +0000 UTC

如何在游戏“煮过头”中进行控制?

  • 772

我想让玩家控制就像在“Overcooked”游戏中一样。

游戏预告片。

我目前的球员管理。

在此处输入图像描述

播放器控制器.cs

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

public class PlayerControllerTransform : MonoBehaviour {

    private string moveInputAxis = "Vertical";
    private string turnInputAxis = "Horizontal";

    public float rotationRate = 360f;
    public float moveSpeed = 1;


    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () 
    {
        float moveAxis = Input.GetAxis (moveInputAxis);
        float turnAxis = Input.GetAxis (turnInputAxis);

        //Обновляет каждый кадр наше положение и поворот
        ApplyInput (moveAxis, turnAxis);
    }

    private void ApplyInput(float moveInput, float turnInput)
    {
        Move (moveInput);
        Turn(turnInput);
    }

    private void Move(float input)
    {
        transform.Translate (Vector3.forward*input*moveSpeed);//Можно добавить Time.DeltaTime
    }

    private void Turn(float input)
    {
        transform.Rotate (0,input * rotationRate * Time.deltaTime,0);
    }
}

问题是什么。游戏里我点了(WASD),鼻子转过去就走了。(据我了解)对我来说,此刻的操控更像是操控一辆汽车。AD负责转牌。W-前进,S-后退。

因此,我想让控件类似于游戏。

ps 更多游戏视频,更好地了解游戏控制。

感谢您的关注。

unity3d
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    user302909
    2020-01-14T07:14:47Z2020-01-14T07:14:47Z

    一般来说,像“游戏 X 是如何做 Y”这样的问题最好向开发者自己提出。并不是因为有人“太懒惰”回答这些问题,而仅仅是因为从另一个 1v1 游戏中重现某些东西通常非常困难。


    当然这可以通过另一种方式完成,但我决定经历两个阶段:

    1. 基于输入的字符旋转
    2. 移动角色transform.forward,因为这个游戏中的角色总是只面向前方移动

    数据输入

    这里的一切都尽可能简单,并且与问题中的选项没有区别,但我将整个事情写成一个向量,以便稍后我可以通过它获得角度和其他必要的东西:

    private Vector3 moveVector;
    
    ...
    
    void HandleInput() {
        moveVector.x = Input.GetAxis("Horizontal");
        moveVector.z = Input.GetAxis("Vertical");
    }
    

    回转

    似乎可以简单地使用

    transform.Rotate(Vector3.up, Vector3.Angle(transform.forward, moveVector));
    

    但Vector3.Angle返回向量之间的最小角度,即 从 0 到 180,当旋转从 0 到 360 的角度时,会导致以下结果:

    在此处输入图像描述

    摆脱这种情况的一种方法是编写自己的函数来确定角度范围 [0..360] 的向量之间的角度:

    float Angle360(Vector3 from, Vector3 to, Vector3 right) {
        float angle = Vector3.Angle(from, to);
        return (Vector3.Angle(right, to) > 90f) ? 360f - angle : angle;
    }
    

    在谷歌中很容易找到这样的功能——我不想用它的解释来加重这个问题。

    然后我们将整个事情应用到Update:

    void Update () {
        HandleInput();
    
        transform.Rotate(Vector3.up, Angle360(transform.forward, moveVector, transform.right));
    }
    

    我们得到了我们几乎需要的旋转:

    在此处输入图像描述


    移动

    一切都几乎是基本的:它使用Transform.Translate,不要忘记为速度添加一个变量:

    public float speed = 2f;
    
    ...
    
    transform.Translate(transform.forward * speed * Time.deltaTime, Space.World);
    

    这段代码将不断地向其本地“直线”方向移动对象。但我们只想在用户输入时移动它。

    摆脱这种情况的合乎逻辑的方法是使用向量 的模moveVector,之前已经对其进行了归一化,以便获得 [0..1] 范围内的值:

    transform.Translate(
        moveVector.normalized.sqrMagnitude * transform.forward * speed * Time.deltaTime,
        Space.World
    );
    

    在这种情况下,您可以简单地使用模数的平方,因为模数的平方始终是0, 或1, 和sqrt(1) == 1/-1, sqrt(0) == 0。-1出于显而易见的原因,我们并不担心。

    但纯粹是凭感觉——我没有测量结果,完全没有这个模块会更容易,像这样做:

    float Moves() {
        if(moveVector.x != 0 || moveVector.z != 0) {
            return 1f;
        }
        else {
            return 0f;
        }
    }
    

    值得注意的是,这种方法总是会输出一个为1的运动向量。如果游戏支持游戏手柄,其中摇杆可以在两个轴[0..1]上输出值,最好使用向量模块。

    并将此方法的结果代入Translate.


    最后,我们得到了这样的某种组件:

    public class OvercookedLikeMovement : MonoBehaviour {
    
        public float speed = 2f;
    
        private Vector3 moveVector;
    
        void Update () {
            HandleInput();
    
            transform.Rotate(Vector3.up, Angle360(transform.forward, moveVector, transform.right));
    
            transform.Translate(
                Moves() * transform.forward * speed * Time.deltaTime,
                Space.World
            );
        }
    
        void HandleInput() {
            moveVector.x = Input.GetAxis("Horizontal");
            moveVector.z = Input.GetAxis("Vertical");
        }
    
        float Moves() {
            if(moveVector.x != 0 || moveVector.z != 0)
                return 1f;
            else
                return 0f;
        }
    
        float Angle360(Vector3 from, Vector3 to, Vector3 right) {
            float angle = Vector3.Angle(from, to);
            return (Vector3.Angle(right, to) > 90f) ? 360f - angle : angle;
        }
    }
    

    统一的结果:

    在此处输入图像描述


    附言

    可以看出,物体有时会突然移动。造成这种情况的原因是物体的旋转角度发生了急剧变化,这不是一个错误,但上面代码的自然结果和没有插值的更清洁是无法做到的。

    我会在你的位置做什么?

    我会关注 Unity 的 Tween 引擎的方向,使用它你可以平滑整个事物并使其更自然,或者其他什么。但就我而言,目前的结果与 OverCooked 非常相似。

    • 8

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5