Unity combate juego de ovnis
Descripción general
Usa la unidad para realizar un simple juego de platillos voladores y anota cuando alcances el objetivo correspondiente. Hay cinco flechas en un juego.
Ideas de diseño
El diagrama UML es el siguiente
Definir componentes
-
arco y flecha
Consta de dos partes: la punta de flecha y el cuerpo de flecha.
La flecha es una cápsula relativamente pequeña que monta el colisionador. El cuerpo de la flecha es un material gratuito descargado de la Tienda de activos
-
objetivo
Compuesto por cinco cilindros concéntricos con diferentes alturas, cada cilindro está montado
RingData
y corresponde a una puntuación diferente
Código
CCShootAction
: Implementar el evento de lanzamiento de la flecha.
public class CCShootAction : SSAction
{
Vector3 force;
Vector3 wind;
private CCShootAction(){}
// Start is called before the first frame update
public override void Start()
{
gameObject.transform.parent = null;
gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
// force = new Vector3(0, 0, 30);
// Impulse:向此刚体添加瞬时力冲击,考虑其质量。
gameObject.GetComponent<Rigidbody>().AddForce(force, ForceMode.Impulse);
gameObject.GetComponent<Rigidbody>().AddForce(wind, ForceMode.Impulse);
gameObject.GetComponent<Rigidbody>().isKinematic = false;
}
// Update is called once per frame
public override void Update()
{
}
public override void FixedUpdate(){
// 箭飞到场外或者中靶
if(this.transform.position.z > 35 || this.transform.tag == "onTarget"){
Debug.Log("回调");
this.destroy = true;
this.enable = false;
this.callback.SSActionEvent(this, SSActionEventType.Completed, 0, null, gameObject);
}
}
public static CCShootAction GetSSAction(Vector3 wind){
CCShootAction shoot = CreateInstance<CCShootAction>();
shoot.force = new Vector3(0, 0, 40);
shoot.wind = wind;
return shoot;
}
}
CCShootActionManager
: Realice la gestión de la acción de tiro con arco.
public class CCShootActionManager : SSActionManager
{
public FirstController firstController;
public CCShootAction shoot;
// Start is called before the first frame update
protected void Start()
{
firstController = (FirstController)SSDirector.GetInstance().CurrentScenceController;
firstController.actionManager = this;
}
public void Shoot(GameObject arrow, Vector3 wind){
Debug.Log("Shoot");
shoot = CCShootAction.GetSSAction(wind);
this.RunAction(arrow, shoot, this);
}
}
TrembleAction
: La acción de temblor después de que golpea la flecha, llamada en la función de devolución de llamada
public class TrembleAction : SSAction
{
float tremble_radius = 0.05f;
float tremble_time = 0.5f;
GameObject arrow;
Vector3 arrow_pos;
private TrembleAction(){}
public static TrembleAction GetSSAction()
{
TrembleAction tremble_action = CreateInstance<TrembleAction>();
return tremble_action;
}
// Start is called before the first frame update
public override void Start()
{
//得到箭中靶时的位置
arrow_pos = gameObject.transform.position;
// this.transform.Translate(new Vector3(0, 0, 0.5f));
Debug.Log(gameObject.transform.name);
}
// Update is called once per frame
public override void Update()
{
tremble_time -= Time.deltaTime;
//需要继续颤抖
if(tremble_time > 0){
// gameObject.transform.Translate(new Vector3(0.02f, 0, 0));
Vector3 head_pos = gameObject.transform.position;
float x = arrow_pos.x + Random.RandomRange(-0.05f, 0.05f);
float y = arrow_pos.y + Random.RandomRange(-0.05f, 0.05f);
float z = arrow_pos.z;
gameObject.transform.position = new Vector3(x, y, z);
}
else{
gameObject.transform.position = arrow_pos;
}
// else{
// transform.position = arrow_pos;
// this.destroy = true;
// this.callback.SSActionEvent(this);
// }
}
}
Aplicación específica SSActionManager
en
public void SSActionEvent(SSAction source,
SSActionEventType events = SSActionEventType.Completed,
int intParam = 0,
string strParam = null,
GameObject arrow = null){
TrembleAction trembleAction = TrembleAction.GetSSAction();
this.RunAction(arrow, trembleAction, this);
}
ArrowFactory
: Fábrica de flechas, utilizada para producir y lanzar arcos y flechas.
public class ArrowFactory : MonoBehaviour
{
private List<GameObject> used;
private List<GameObject> free;
public GameObject arrow;
FirstController firstController;
// Start is called before the first frame update
void Start()
{
firstController = (FirstController)SSDirector.GetInstance().CurrentScenceController;
used = new List<GameObject>();
free = new List<GameObject>();
arrow = null;
}
// Update is called once per frame
void Update()
{
}
public GameObject GetArrow(){
if(free.Count > 0){
arrow = free[0];
free.Remove(free[0]);
if(arrow.tag == "onTarget")//箭在靶子上
{
arrow.GetComponent<Rigidbody>().isKinematic = false;
arrow.tag = "arrow";
arrow.transform.GetChild(0).gameObject.SetActive(true);
}
arrow.SetActive(true);
}
else{
arrow = Instantiate(Resources.Load<GameObject>("Prefabs/arrow1"));
arrow.GetComponent<Rigidbody>().isKinematic = false;
// arrow.AddComponent<Rigidbody>();
}
// firstController = (FirstController)SSDirector.GetInstance().CurrentScenceController;
// Transform pos = firstController.bow.transform.GetChild(0);
// arrow.transform.position = pos.transform.position;
arrow.transform.parent = firstController.bow.transform; // 把arrow附加在bow上,跟随着bow移动
arrow.transform.position = firstController.bow.transform.position;
used.Add(arrow);
return arrow;
}
public void FreeArrow(GameObject arrow){
foreach(GameObject aa in used){
Debug.Log("befreed");
if(aa.gameObject.GetInstanceID() == arrow.GetInstanceID()){
arrow.SetActive(false);
used.Remove(aa);
aa.tag = "arrow";
break;
}
}
}
public void Clear(){
foreach(GameObject dd in used){
dd.transform.position = new Vector3(0, 0, 100);
Destroy(dd);
}
foreach(GameObject dd in free){
dd.transform.position = new Vector3(0, 0, 100);
Destroy(dd);
}
used.Clear();
free.Clear();
}
}
RingData
: Montado en cada anillo, se utiliza para definir las puntuaciones de diferentes anillos
public class RingData : MonoBehaviour {
public int score;
public void Start(){
if(this.gameObject.name=="1"){
score = 5;
}
else if(this.gameObject.name=="2"){
score = 4;
}
else if(this.gameObject.name=="3"){
score = 3;
}
else if(this.gameObject.name=="4"){
score = 2;
}
else{
score = 1;
}
}
}
RingController
: Controle los eventos de impacto del anillo, la puntuación, las acciones de temblor de devolución de llamada
public class RingController : MonoBehaviour
{
public ScoreRecorder scoreRecorder;
public ISceneController sceneController;
// Start is called before the first frame update
void Start()
{
sceneController = SSDirector.GetInstance().CurrentScenceController as FirstController;
scoreRecorder = Singleton<ScoreRecorder>.Instance;
this.gameObject.AddComponent<RingData>();
}
// Update is called once per frame
void OnTriggerEnter(Collider arrowCollider){
Debug.Log("碰撞!");
Transform arrow = arrowCollider.gameObject.transform.parent;
Debug.Log(arrow.gameObject.name);
if(arrow == null){
Debug.Log("null");
return;
}
scoreRecorder.RecordScore(this.gameObject.GetComponent<RingData>().score);
Debug.Log("Score:"+this.gameObject.GetComponent<RingData>().score);
arrow.GetComponent<Rigidbody>().isKinematic = true;
arrow.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
arrowCollider.gameObject.SetActive(false);
arrow.tag = "onTarget";
}
}