Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d Unity在更新Rigidbody2D';s属性_Unity3d - Fatal编程技术网

Unity3d Unity在更新Rigidbody2D';s属性

Unity3d Unity在更新Rigidbody2D';s属性,unity3d,Unity3d,我试图实现一种让玩家在正方形和圆形之间切换的方法。为了使这项工作正常,我的播放器对象有两个碰撞器,一个圆和一个盒子。在它们之间切换时,我只需禁用一个碰撞器并启用另一个,然后切换当前的精灵。当我从圆切换到正方形时,问题就出现了 我希望正方形能够在地板上滑动,而圆圈应该滚动。为了使开关无缝,我必须重新定向正方形,使其与当前速度对齐,并移除角速度。这似乎是可行的,但是有一小段帧(或帧),其中正方形的旋转与圆在切换之前的旋转相同。这对我来说似乎很奇怪,因为新的旋转和精灵是在代码的同一部分中更改的。这是一

我试图实现一种让玩家在正方形和圆形之间切换的方法。为了使这项工作正常,我的播放器对象有两个碰撞器,一个圆和一个盒子。在它们之间切换时,我只需禁用一个碰撞器并启用另一个,然后切换当前的精灵。当我从圆切换到正方形时,问题就出现了

我希望正方形能够在地板上滑动,而圆圈应该滚动。为了使开关无缝,我必须重新定向正方形,使其与当前速度对齐,并移除角速度。这似乎是可行的,但是有一小段帧(或帧),其中正方形的旋转与圆在切换之前的旋转相同。这对我来说似乎很奇怪,因为新的旋转和精灵是在代码的同一部分中更改的。这是一段展示这个问题的视频

如果这是由于渲染对象的方式导致的问题,我可以用另一种方法解决。我只是想了解为什么会发生这种情况

切换时将特性从圆形更改为方形的零件的代码段:

else if (Input.GetKeyDown("2"))
        {
            // Update rotation of box to velocity:
            float newAngleRadians = Mathf.Atan2(rb.velocity.y, rb.velocity.x);
            float newAngleDegrees = newAngleRadians * 180 / Mathf.PI;
            rb.rotation = newAngleDegrees;
            rb.angularVelocity = 0;
            Debug.Log(rb.rotation);

            playerShape = Shape.SQUARE;
            spriteRenderer.sprite = spriteArray[1];
            circleCollider.enabled = false;
            boxCollider.enabled = true;

            updateShape = true;
        }
将刚体设置为newAngleDegrees后直接记录其角度,表明旋转设置正确,但问题仍然存在

为了以防万一,脚本的完整代码:

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

public class scr_StateMachine : MonoBehaviour
{
    // Types of shapes:
    public enum Shape { SQUARE, CIRCLE, TRIANGLE }

    // Variables:
    public Rigidbody2D rb;
    public SpriteRenderer spriteRenderer;
    public Sprite[] spriteArray;
    public Shape playerShape;
    public CircleCollider2D circleCollider;
    public BoxCollider2D boxCollider;

    private bool updateShape;


    void Start()
    {
        playerShape = Shape.CIRCLE;
        updateShape = true;
    }

    void Update()
    {
        // Get input for shape change:
        if(Input.GetKeyDown("1"))
        {
            playerShape = Shape.CIRCLE;
            spriteRenderer.sprite = spriteArray[0];
            circleCollider.enabled = true;
            boxCollider.enabled = false;

            updateShape = true;
        }
        else if (Input.GetKeyDown("2"))
        {
            // Update rotation of box to velocity:
            float newAngleRadians = Mathf.Atan2(rb.velocity.y, rb.velocity.x);
            float newAngleDegrees = newAngleRadians * 180 / Mathf.PI;
            rb.rotation = newAngleDegrees;
            rb.angularVelocity = 0;
            Debug.Log(rb.rotation);

            playerShape = Shape.SQUARE;
            spriteRenderer.sprite = spriteArray[1];
            circleCollider.enabled = false;
            boxCollider.enabled = true;

            updateShape = true;
        }

        // Update movement script's shape:
        if (updateShape)
        {
            GetComponent<scr_Movement>().shape = playerShape;
            updateShape = false;
        }
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类scr_状态机:单行为
{
//形状类型:
公共枚举形状{正方形、圆形、三角形}
//变量:
公共刚体2d rb;
公共喷壶;
公共精灵[]精灵阵;
公众人物;
公共环路集线器2D环路集线器;
公共boxCollider R2D boxCollider;
私有布尔更新图像;
void Start()
{
playerShape=Shape.CIRCLE;
updateShape=true;
}
无效更新()
{
//获取形状更改的输入:
if(Input.GetKeyDown(“1”))
{
playerShape=Shape.CIRCLE;
spriteRenderer.sprite=spriteArray[0];
circleCollider.enabled=true;
boxCollider.enabled=false;
updateShape=true;
}
else if(Input.GetKeyDown(“2”))
{
//将长方体的旋转更新为速度:
float newAngleRadians=Mathf.Atan2(rb.velocity.y,rb.velocity.x);
浮动新角度度=新角度弧度*180/Mathf.PI;
rb.旋转=新角度度;
rb.角速度=0;
Debug.Log(rb.rotation);
playerShape=Shape.SQUARE;
spriteRenderer.sprite=spriteArray[1];
circleCollider.enabled=false;
boxCollider.enabled=true;
updateShape=true;
}
//更新移动脚本的形状:
if(updateShape)
{
GetComponent().shape=播放者;
updateShape=false;
}
}
}

我认为问题在于
刚体
/
刚体2d
物理应用于固定时间步长(请参阅)。因此,是的,在强大的设备上,在下一个
FixedUpdate
调用开始并更改
Rigidbody
/
Rigidbody2D
行为之前渲染某些帧肯定是可能的

我想你能做的就是等待下一个
FixedUpdate
呼叫的更改,例如使用

公共类scr\U状态机:单行为
{
//形状类型:
公共枚举形状{正方形、圆形、三角形}
//变量:
公共刚体2d rb;
公共喷壶;
公共精灵[]精灵阵;
公众人物;
公共环路集线器2D环路集线器;
公共boxCollider R2D boxCollider;
[Serialized Field]私人scr_运动;
void Start()
{
如果(!\u scrMovement)\u scrMovement=GetComponent();
改变形状(形状.圆);
}
//仍然在更新中获取用户输入
无效更新()
{
//获取形状更改的输入:
if(Input.GetKeyDown(“1”))
{
改变形状(形状.圆);
}
else if(Input.GetKeyDown(“2”))
{
改变形状(形状.正方形);
}
}
私有void ChangeShape(Shape newShape)
{
//如果出现相同的形状,我们已经无事可做了
if(newShape==剧组)返回;
//停止任何已经运行的协同程序,因为我们只想处理FixUpdate调用之前的最后一个输入
// https://docs.unity3d.com/ScriptReference/MonoBehaviour.StopAllCoroutines.html
StopAllCoroutines();
//为新形状启动新的协同程序
//看https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
Start例程(ChangeShapeInExtFixedUpdate(newShape));
}
私有IEnumerator ChangeShapeInExtFixedUpdate(形状新闻形状)
{
//以防万一,如果同样的形状出现,我们已经无事可做了
if(新闻形态==剧组)产量突破;
//等待下一个FixeUpdate调用
//看https://docs.unity3d.com/ScriptReference/WaitForFixedUpdate.html
返回新的WaitForFixedUpdate();
//现在根据新形状进行所需的更改
circleCollider.enabled=newShape==Shape.CIRCLE;
boxCollider.enabled=newShape==Shape.SQUARE;
交换机(新闻形状)
{
外壳形状.圆形:
spriteRenderer.sprite=spriteArray[0];
打破
case Shape.SQUARE:
//将长方体的旋转更新为速度:
var newAngleRadians=Mathf.Atan2(rb.velocity.y,rb.velocity.x);
//看https://docs.unity3d.com/ScriptReference/Mathf.Rad2Deg.html
纽安格尔度变种