c# - 玩家重生后石头没有在正确的地方产卵
问题描述
当玩家重生时,我希望石头(可以由玩家移动)回到原来的位置。这对我不起作用。相反,石头会在附近的其他位置生成,有时会在地图外生成。所有石头都被标记为石头。
我已经尝试反转向量并反转减法等的符号。
这是播放器脚本。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControll : MonoBehaviour
{
public bool isTouchingGround = false;
public GameObject locater1;
public GameObject locater2;
public GameObject currentCheckPoint;
public GameObject playerPrefab;
public Rigidbody2D myRigidBody;
public GameObject GameMaster;
// Start is called before the first frame update
void Start()
{
isTouchingGround = false;
GameObject MyGameMaster= Instantiate(GameMaster, new Vector3(0, 0, 0), Quaternion.identity);
GameMaster = MyGameMaster;
}
// Update is called once per frame
void Update()
{
if (Input.GetKey("a"))
{
transform.Translate(-0.1f, 0, 0);
}
if (Input.GetKey("d"))
{
transform.Translate(0.1f, 0, 0);
}
if ((Input.GetKey("w") || Input.GetKey("space")) && isTouchingGround == true)
{
myRigidBody.AddForce(new Vector2(0f, 130f));
}
if (locater1.transform.position.y <= locater2.transform.position.y)
{
ReSpawn();
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Platform" || collision.gameObject.tag == "Stone")
{
isTouchingGround = true;
}
}
private void OnCollisionExit2D(Collision2D collision)
{
if ((collision.gameObject.tag == "Platform" || collision.gameObject.tag == "Stone") && locater2.transform.position.y > collision.transform.position.y)
{
isTouchingGround = false;
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "CheckPoint")
{
currentCheckPoint = collision.gameObject;
}
if (collision.gameObject.tag == "Radiation")
{
ReSpawn();
}
}
public void ReSpawn()
{
GameMaster.gameObject.GetComponent<ReverToOriginalPositions>().RevertToOrignalPosition();
GameObject currentPlayer=Instantiate(playerPrefab, currentCheckPoint.transform.position, currentCheckPoint.transform.rotation);
currentPlayer.GetComponent<PlayerControll>().isTouchingGround = false;
Destroy(this.gameObject);
}
}
这是 RememberPositions 脚本。这属于每一块石头都要记住在开始时的位置。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RememberPositions : MonoBehaviour
{
public float StartXPosition;
public float StartYPosition;
float StartRotation;
// Start is called before the first frame update
void Start()
{
StartXPosition = transform.position.x;
StartYPosition = transform.position.y;
StartRotation = transform.rotation.z;
}
// Update is called once per frame
void Update()
{
}
}
这是 RevertToOriginalPosition 脚本。这会将石头恢复到原来的位置。这是在 GameMaster/MasterControll 中。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReverToOriginalPositions : MonoBehaviour
{
public GameObject[] allStones;
// Start is called before the first frame update
void Start()
{
allStones = GameObject.FindGameObjectsWithTag("Stone");
}
// Update is called once per frame
void Update()
{
}
public void RevertToOrignalPosition()
{
for (int i = 0; i < allStones.Length; i++)
{
allStones[i].gameObject.transform.Translate((new Vector3((allStones[i].gameObject.GetComponent<Transform>().position.x- allStones[i].gameObject.GetComponent<RememberPositions>().StartXPosition) , (allStones[i].gameObject.GetComponent<Transform>().position.y- allStones[i].gameObject.GetComponent<RememberPositions>().StartYPosition), 0)));
allStones[i].gameObject.transform.Rotate(0, 0, -allStones[i].gameObject.transform.rotation.z);
}
}
}
这是商店接收者脚本。这是针对另一种称为 Activator 的游戏机制。这不是那么重要,但我还是把它包括在内。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StoreReciever : MonoBehaviour
{
public GameObject reciever;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter2D(Collider2D collision)
{
reciever.gameObject.GetComponent<PolygonCollider2D>().enabled = true;
}
void OnTriggerExit2D(Collider2D collision)
{
reciever.gameObject.GetComponent<PolygonCollider2D>().enabled = false;
}
}
根本没有错误消息。只是石头在他们不应该的地方重生。感谢您的帮助。
解决方案
只需制作一些字段/属性,它们甚至不必是私有静态只读
public static readonly Vector3 StartPos = new Vector3(1.0f, 2.0f, 3.0f);
public static readonly Vector3 StartRot_In_EulerAngles = new Vector3(1.0f, 2.0f, 3.0f);
然后你可以在一个方法中做这样的事情:
public static void ResetMyStones()
{
var allStones = GameObject.FindGameObjectsWithTag("Stone");
foreach(var stone in allStones)
{
stone.transform.position = StartPos;
stone.transform.eulerAngles = StartRot_In_EulerAngles;
}
}
关于欧拉角:
为什么是欧拉角?- 因为 Unity 使用所谓的四元数进行旋转,所以不会发生Gimbal 锁定,但不好的是,如果您不深入了解四元数,您无法真正单独设置 xyz 组件,但是如果您只想设置并获得当前的旋转欧拉角度是完美的,因为您可以使用传统的 x,y,z 组件来设置值。
补充说明:
你的代码有点长而且结构不好,就像ReverToOriginalPositions
应该是一个方法而不是一个组件,也不是所有的东西都必须是从单一行为派生的。
还要删除未使用的Update
方法,如果它在脚本中但未使用它们会产生很小的开销(通常它无法衡量,但在更大的项目中它会影响性能:)),也许如果你的游戏是这样构建的,你可以存储所有当前GameManager 类列表中的石头,因此您无需调用GameObject.FindGameObjectsWithTag("Stone");
推荐阅读
- javascript - 如何在IOS中播放和链接html5视频?
- angular - syncfusion ejs调度程序角度
- firebase - Firebase Auth 中用户的 UID 是否更改?
- ruby-on-rails-5 - Rails 5 活动记录查询未显示 left_outer_joins 属性
- pytorch - PyTorch:如何检查训练过程中是否有一些权重没有改变?
- javascript - 动态 CSS 网格生成
- python - python 注册表中缺少图形操作
- c++ - C++ 反转输入顺序并将其打印为 Char*
- sql - Data Studio CASE 错误 - THEN/ELSE 参数的类型不兼容:TEXT/NUMBER
- swift - Firebase RTDB 数据未显示在 SwiftUI 列表视图中