Unity Button 滚动 3D 骰子寻找按钮上的 Rigidbody 而不是骰子对象
Unity Button to roll 3D dice looking for Rigidbody on the button instead of the die object
我是 Unity 的新手,一直在尝试掷骰子。我遇到了一组教程,这些教程允许我创建一个 3d 模具(该模具使用 Rigidbody 和 Mesh Collider)并将其编写为在按下空格键时滚动的脚本,如下所示:
Dice.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dice : MonoBehaviour
{
Rigidbody rb;
bool hasLanded;
bool thrown;
Vector3 initPosition;
public int diceValue;
public DiceSide[] diceSides;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
initPosition = transform.position;
rb.useGravity = false;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)){
RollDice();
}
if (rb.IsSleeping() && !hasLanded && thrown)
{
hasLanded = true;
rb.useGravity = false;
rb.isKinematic = true;
SideValueCheck();
}
else if (rb.IsSleeping() && hasLanded && diceValue == 0)
{
RollAgain();
}
}
void RollDice()
{
if (!thrown && !hasLanded)
{
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0,500), Random.Range(0, 500));
}
else if (thrown && hasLanded)
{
Reset();
}
}
void Reset()
{
transform.position = initPosition;
thrown = false;
hasLanded = false;
rb.useGravity = false;
rb.isKinematic = false;
}
void RollAgain()
{
Reset();
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0, 500), Random.Range(0, 500));
}
void SideValueCheck()
{
diceValue = 0;
foreach (DiceSide side in diceSides)
{
if (side.OnGround())
{
diceValue = side.sideValue;
Debug.Log(diceValue + " has been rolled!");
}
}
}
}
DiceSide.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DiceSide : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
bool onGround;
public int sideValue;
private void OnTriggerStay(Collider col)
{
if(col.tag == "Ground")
{
onGround = true;
}
}
private void OnTriggerExit(Collider col)
{
if(col.tag == "Ground")
{
onGround = true;
}
}
public bool OnGround()
{
return onGround;
}
}
骰子的每一面都有一个球体,DiceSide.cs 附在球体上,包含与给定面相反的边值,Dice.cs 附在主骰子本身上。
以上所有都工作得很好。
我面临的问题是调整它而不是按下一个键(在这种情况下,空格键)我想在点击一个按钮后掷骰子。
为此,我修改了 Dice.cs 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dice : MonoBehaviour
{
Rigidbody rb;
bool hasLanded;
bool thrown;
Vector3 initPosition;
public int diceValue;
public DiceSide[] diceSides;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
initPosition = transform.position;
rb.useGravity = false;
}
// Update is called once per frame
void Update()
{
if (rb.IsSleeping() && !hasLanded && thrown)
{
hasLanded = true;
rb.useGravity = false;
rb.isKinematic = true;
SideValueCheck();
}
else if (rb.IsSleeping() && hasLanded && diceValue == 0)
{
RollAgain();
}
}
public void RollDice()
{
if (!thrown && !hasLanded)
{
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0,500), Random.Range(0, 500));
}
else if (thrown && hasLanded)
{
Reset();
}
}
void Reset()
{
transform.position = initPosition;
thrown = false;
hasLanded = false;
rb.useGravity = false;
rb.isKinematic = false;
}
void RollAgain()
{
Reset();
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0, 500), Random.Range(0, 500));
}
void SideValueCheck()
{
diceValue = 0;
foreach (DiceSide side in diceSides)
{
if (side.OnGround())
{
diceValue = side.sideValue;
Debug.Log(diceValue + " has been rolled!");
}
}
}
}
但是当我将Dice.cs脚本拖到按钮上时如下:
我收到 Unity 的错误提示
MissingComponentException: There is no 'Rigidbody' attached to the "Button-RollDice" game object, but a script is trying to access it.
You probably need to add a Rigidbody to the game object "Button-RollDice". Or your script needs to check if the component is attached before using it.
Dice.Update () (at Assets/Dice.cs:35)
我知道代码正在寻找按钮上的刚体而不是骰子,但我不知道如何修改我的代码以使其按预期作用于骰子。
谢谢。
骰子脚本仍需要位于 Dice 对象上。您需要一个带有 OnClick 事件的中间脚本来分配给带有对 Dice 脚本的引用的按钮,该脚本随后可以调用 RollDice。
类似于:
public class ButtonHandler : MonoBehavior
{
// Assign dice game object to script in editor
public GameObject DiceGameObject;
private Dice dice;
void Awake()
{
// Retrieve the script from the gameobject
dice = diceGameObject.GetComponent<Dice>();
}
public void RollDiceOnClick()
{
// Call the roll dice method
dice.RollDice();
}
}
您可以将 RollDiceOnClick() 方法分配给按钮的 OnClick 事件(而不是 RollDice)。
然后将骰子游戏对象拖到 DiceGameObject 属性 上,一切都应该 link 向上
我是 Unity 的新手,一直在尝试掷骰子。我遇到了一组教程,这些教程允许我创建一个 3d 模具(该模具使用 Rigidbody 和 Mesh Collider)并将其编写为在按下空格键时滚动的脚本,如下所示:
Dice.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dice : MonoBehaviour
{
Rigidbody rb;
bool hasLanded;
bool thrown;
Vector3 initPosition;
public int diceValue;
public DiceSide[] diceSides;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
initPosition = transform.position;
rb.useGravity = false;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)){
RollDice();
}
if (rb.IsSleeping() && !hasLanded && thrown)
{
hasLanded = true;
rb.useGravity = false;
rb.isKinematic = true;
SideValueCheck();
}
else if (rb.IsSleeping() && hasLanded && diceValue == 0)
{
RollAgain();
}
}
void RollDice()
{
if (!thrown && !hasLanded)
{
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0,500), Random.Range(0, 500));
}
else if (thrown && hasLanded)
{
Reset();
}
}
void Reset()
{
transform.position = initPosition;
thrown = false;
hasLanded = false;
rb.useGravity = false;
rb.isKinematic = false;
}
void RollAgain()
{
Reset();
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0, 500), Random.Range(0, 500));
}
void SideValueCheck()
{
diceValue = 0;
foreach (DiceSide side in diceSides)
{
if (side.OnGround())
{
diceValue = side.sideValue;
Debug.Log(diceValue + " has been rolled!");
}
}
}
}
DiceSide.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DiceSide : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
bool onGround;
public int sideValue;
private void OnTriggerStay(Collider col)
{
if(col.tag == "Ground")
{
onGround = true;
}
}
private void OnTriggerExit(Collider col)
{
if(col.tag == "Ground")
{
onGround = true;
}
}
public bool OnGround()
{
return onGround;
}
}
骰子的每一面都有一个球体,DiceSide.cs 附在球体上,包含与给定面相反的边值,Dice.cs 附在主骰子本身上。
以上所有都工作得很好。
我面临的问题是调整它而不是按下一个键(在这种情况下,空格键)我想在点击一个按钮后掷骰子。
为此,我修改了 Dice.cs 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dice : MonoBehaviour
{
Rigidbody rb;
bool hasLanded;
bool thrown;
Vector3 initPosition;
public int diceValue;
public DiceSide[] diceSides;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
initPosition = transform.position;
rb.useGravity = false;
}
// Update is called once per frame
void Update()
{
if (rb.IsSleeping() && !hasLanded && thrown)
{
hasLanded = true;
rb.useGravity = false;
rb.isKinematic = true;
SideValueCheck();
}
else if (rb.IsSleeping() && hasLanded && diceValue == 0)
{
RollAgain();
}
}
public void RollDice()
{
if (!thrown && !hasLanded)
{
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0,500), Random.Range(0, 500));
}
else if (thrown && hasLanded)
{
Reset();
}
}
void Reset()
{
transform.position = initPosition;
thrown = false;
hasLanded = false;
rb.useGravity = false;
rb.isKinematic = false;
}
void RollAgain()
{
Reset();
thrown = true;
rb.useGravity = true;
rb.AddTorque(Random.Range(0, 500), Random.Range(0, 500), Random.Range(0, 500));
}
void SideValueCheck()
{
diceValue = 0;
foreach (DiceSide side in diceSides)
{
if (side.OnGround())
{
diceValue = side.sideValue;
Debug.Log(diceValue + " has been rolled!");
}
}
}
}
但是当我将Dice.cs脚本拖到按钮上时如下:
我收到 Unity 的错误提示
MissingComponentException: There is no 'Rigidbody' attached to the "Button-RollDice" game object, but a script is trying to access it. You probably need to add a Rigidbody to the game object "Button-RollDice". Or your script needs to check if the component is attached before using it. Dice.Update () (at Assets/Dice.cs:35)
我知道代码正在寻找按钮上的刚体而不是骰子,但我不知道如何修改我的代码以使其按预期作用于骰子。
谢谢。
骰子脚本仍需要位于 Dice 对象上。您需要一个带有 OnClick 事件的中间脚本来分配给带有对 Dice 脚本的引用的按钮,该脚本随后可以调用 RollDice。
类似于:
public class ButtonHandler : MonoBehavior
{
// Assign dice game object to script in editor
public GameObject DiceGameObject;
private Dice dice;
void Awake()
{
// Retrieve the script from the gameobject
dice = diceGameObject.GetComponent<Dice>();
}
public void RollDiceOnClick()
{
// Call the roll dice method
dice.RollDice();
}
}
您可以将 RollDiceOnClick() 方法分配给按钮的 OnClick 事件(而不是 RollDice)。
然后将骰子游戏对象拖到 DiceGameObject 属性 上,一切都应该 link 向上