Galeria de tiro. Unity 3D Raycast Shooting

Material didático para a escola de programação. Parte 17

Tutoriais anteriores podem ser encontrados aqui:
  1. Nave espacial





  2. Dominó





  3. Pássaro abano





  4. Sala de gravidade





  5. Platformer





  6. Árvores (plugin SpeedTree)





  7. Modelando uma casa no SketchUp





  8. Casa na floresta





  9. Efeito de chuva. Partículas





  10. Bilhar





  11. Caráter líquido





  12. Aderindo e trabalhando com o Sistema de Eventos





  13. Sintetizador Unity 3D





  14. Hovercraft





  15. Ragdolls no Unity 3D





  16. Como funcionam os vetores. Unity 3D Basketball





Neste projeto, vamos considerar o processo de trabalho:





  • com raycasts e vetores;





  • com métodos de outras classes personalizadas;





  • com AudioSource e com Rigidbody por meio de código;





  • três componentes principais de uma tacada que afetam psicologicamente o jogador (som, luz e brilho, animação e o rastro da tacada);





  • instanciação de pré-fabricados.





Os temas principais do projeto são precisamente raycasts e vetores. Neste último, é necessário dedicar bastante tempo todos os dias, e explicar como funcionam com exemplos simples. Mas se você conseguiu concluir um projeto rapidamente com os alunos, então nesta lição será conveniente considerar o sistema mecanim.





Ordem de execução

Crie um novo projeto, importe o ativo anexado .





Além dos recursos padrão, o pacote possui um plugin de terceiros para pintar decalques. Seu trabalho não é abordado no contexto desta lição.





O projeto de aula é dividido em 2 partes - campo de tiro e granadas.





Galeria de tiro

- . , , , , .





, , .





DecalShooter, , , . .

, . , Y , CapsuleCollider MeshCollider Convex. , , point light, , AudioSource , Rigidbody Continius Dynamic isKinematik. AudioSource PlayOnAwake .





Target, .





, . .





using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Target : MonoBehaviour {
    public GameObject light;
    public Rigidbody rig;
    public AudioSource src;
 
    bool enabled = true;
 
    // Use this for initialization 
    void Start() {
        rig = GetComponent<Rigidbody>();
        src = GetComponent<AudioSource>(); 
    }
 
    // Update is called once per frame 
    void Update() {
 
    }
 
    public void shoot() {
        if (!enabled) {
           return;
        }
 
        rig.isKinematic = false; 
        light.SetActive(false); 
        src.Play();
 
        enabled = false;
    }
 
}

      
      



 ​shoot,​ , . - DecalShooter  ​shoot. :





   if (Input.GetKeyDown(KeyCode.Mouse0)) {
            time = 0.3f; 
            ShootSource.Play(); 
            anim.Play("fire"); 
            Muzzleflash.SetActive(true);
            //   
            RaycastHit hitInfo;
            Vector3 fwd = transform.TransformDirection(Vector3.forward); 
            
            if (Physics.Raycast(transform.position, fwd, out hitInfo, 100f)) {
                GameObject go = Instantiate(
                    DecalPrefab,
                    hitInfo.point, 
                    Quaternion.LookRotation(
                        Vector3.Slerp(-hitInfo.normal, fwd, normalization) 
                    )
                ) as GameObject;
                go.GetComponent<DecalUpdater>().UpdateDecalTo(
                    hitInfo.collider.gameObject, 
                    true
                );
                Vector3 explosionPos = hitInfo.point;
                Target trg = hitInfo.collider.GetComponent<Target>();
                
                if (trg) {
                    trg.shoot();
                }
                
                Rigidbody rb = hitInfo.collider.GetComponent<Rigidbody>();
                
                if (rb != null) {
                    rb.AddForceAtPosition(fwd * power, hitInfo.point, ForceMode.Impulse);
                    Debug.Log("rb!");
                } 
            }
            //   
        }
      
      



hitInfo , ,  ​shoot.​ , , . , . , , . Target :





light.SetActive(false);
      
      







light.GetComponent<Light>().color = Color.red;
      
      



, .





.





, - .





using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class Lenght :  MonoBehaviour {
    public Text Dalnost;
    float rasstoyanie = 0; //     
 
    // Use this for initialization 
    void Start() {
 
    }
 
    // Update is called once per frame 
    void Update() {
        RaycastHit hitInfo;
        
        if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hitInfo, 200)) {
            rasstoyanie = hitInfo.distance;
            Dalnost.text = rasstoyanie.ToString();
        }
    }
}
      
      



FPScontroller/FirstPersonCharacter. Canvas , .

, , .

.





- . , . , .





using System.Collections;
using System.Collections.Generic; 
using UnityEngine;
using UnityEngine.UI;
 
public class Length :  MonoBehaviour {
    public Text Dalnost;
    float rasstoyanie = 0; //      
    public GameObject sharik;
 
    // Use this for initialization
    void Start() {
 
    }
 
    // Update is called once per frame 
    void Update() {
        RaycastHit hitInfo; 
        
        if(Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), outhitInfo, 200)) {
            rasstoyanie = hitInfo.distance; 
            Dalnost.text = rasstoyanie.ToString ();
            if(Input.GetKeyDown(KeyCode.Mouse1)) {
                GameObject go = Instantiate(
                    sharik, 
                    transform.position + Vector3.Normalize(hitInfo.point - transform.position), 
                    transform.rotation
                );
                Rigidbody rig = go.GetComponent<Rigidbody>();
                rig.velocity = Vector3.Normalize(hitInfo.point - transform.position) * 10;
            } 
        }
    } 
}
      
      



- ? , . . .. , , . . Grenade.





using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Grenade :  MonoBehaviour {
    public Transform explosionPrefab;
 
    void OnCollisionEnter(Collision collision) {
        ContactPoint contact = collision.contacts[0];
        
        // Rotate the object so that the y-axis faces along the normal of the surface
        Quaternion rot = Quaternion.FromToRotation(Vector3.up, contact.normal);
        Vector3 pos = contact.point; 
        Instantiate(explosionPrefab, pos, rot);
        Destroy(gameObject);
    }
}
      
      



, Body Convex, RIgidbody . .





, , , .





. , AudioSource PlayOnAwake , Spital Blend 90 3 .





Para trabalhar todos os efeitos e propagação do Rigidbody corretamente, você precisa criar outro script. Vamos chamá-lo de Explosão:





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

public class Explosion :  MonoBehaviour {
    public float radius = 5.0f;
    public float power = 10.0f;
    public GameObject svet;

    void Start() {
        Destroy(svet, 0.1f);

        Vector3 explosionPos = transform.position;
        Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);

        foreach(Collider hit in colliders) {
            Rigidbodyrb = hit.GetComponent<Rigidbody>();
            if (rb != null) {
                rb.AddExplosionForce(power, explosionPos, radius, 3.0f);
            }
        }
    }
}
      
      



Você precisa jogá-lo no efeito de explosão e criar um pré-fabricado.





Este pré-fabricado é usado no script da granada para criar uma explosão.





Feito!








All Articles