Teaching materials for the school of programming. Part 17
Previous tutorials can be found here:
In this project, we will consider the process of work:
with raycasts and vectors;
with methods of other custom classes;
with AudioSource and with Rigidbody via code;
three main components of a shot that psychologically affect the player (sound, light and glow, animation and the trail of the shot);
instantiation of prefabs.
The key themes of the project are precisely raycasts and vectors. The latter, it is necessary to devote quite a lot of time every day, and explain how they work with simple examples. But if you managed to quickly complete a project with students, then in this lesson it will be appropriate to consider the mecanim system.
Execution order
Create a new project, import the attached asset .
In addition to the standard resources, the package has a third-party plugin for painting decals. His work is not covered in the context of this lesson.
The lesson project is divided into 2 parts - shooting range and grenades.
Shooting gallery
- . , , , , .
, , .
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 .
To work out all the effects and spreading of the Rigidbody correctly, you need to create another script. We'll call it Explosion:
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);
}
}
}
}
You need to throw it on the explosion effect and create a prefab.
This prefab is used in the grenade script to create an explosion.
Done!