5 Weapon and other advanced game functions
- Find source project Tutorial_4_Upgrade in Shooter
Weapon compositions
Gun + bullet
- Gun: shoot frequency, ammo, fire direction
- Bullet: damage, speed, damage type
Player to control it
- Player script to handle weapon change, fire, and pick up items
Weapon
lastShootTime
and freezeTime
to implement weapon freeze time。
public void Fire(Vector3 target)
{
if (lastShootTime < freezeTime)
return;
Vector3 dir = target - bulletPos.position;
Vector3 xyProject = Vector3.ProjectOnPlane(dir, Vector3.up);
if (num <= 0)
return;
Vector3 bulletStartPos = bulletPos.position;
bulletStartPos.y = 1;
GameObject g = (GameObject)GameObject.Instantiate(bullet, bulletStartPos, Quaternion.FromToRotation(Vector3.forward, xyProject.normalized));
num--;
lastShootTime = 0f;
}
Calculate fire direction
Calculate fire direction based on mouse position
if (Input.GetButton("Fire1"))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float enter = 0.0f;
Plane firePlane = new Plane(Vector3.up, weaponPos.position);
if (firePlane.Raycast(ray, out enter))
{
desPos = ray.GetPoint(enter);
}
Fire(desPos);
}
Bullet
In Update
to let bullet move in a particular speed. Set bullet game object collider as trigger
type. When collider with others, then check if cause damage.
public void Update()
{
if (bMove)
rb.MovePosition(transform.position + transform.forward * speed * Time.deltaTime);
}
public void OnTriggerEnter(Collider other)
{
switch (other.tag)
{
case Tags.obstacle:
bMove = false;
break;
case Tags.enemy:
break;
default:
return;
}
BeginDamage(other);
}
Grab a gun
Characters can equip a particular weapon.
void Start()
{
if (!weaponPos)
weaponPos = gameObject.transform;
for (int i = 0; i < weapons.Length; i++)
{
weapons[i] = (GameObject)Instantiate(weapons[i], weaponPos.position, Quaternion.identity);
if (gameObject.tag == Tags.enemy)
weapons[i].SendMessage("SetAsEnemy", true);
weapons[i].transform.SetParent(weaponPos);
//weapons[i].SendMessage("SetUsable", i == currWeapon);
weapons[i].gameObject.SetActive(i == currWeapon);
}
}
Cause damage to characters
The bullet from the player will cause damage to enemies, and vice verse.
Different type of bullet will cause different type of damage.
- Common bullet will cause instant damage
- Explosion bullet will damage all characters inside the efficient region
- Consistent bullet will cause damage for a while
- Puncture bullet wouldn’t stop when hit a character
Change weapon
bool NextWeapon(int next)
{
weapons[currWeapon].gameObject.SetActive(false);
currWeapon = Mathf.Abs(currWeapon + next + weapons.Length) % weapons.Length;
weapons[currWeapon].gameObject.SetActive(true);
StopFire(); // stop fire when changing to a new weapon
return true;
}
Use prefabs
Weapon system logic
Instantiate all possible weapons for every character.
But only one of them is currently useable.
- The others are disable
- When the player pick up weapon, corresponding weapon in its weapon list will become usable
When fire, current weapon will try to instantiate a bullet, then bullet script will take over the following process.
- Enemy will fire at the player
- Player will fire at the direction where the mouse point to
Set enemy behavior
Set the enemy tag as Enemy
. Use enemy script to receive damage when shot. When the health of enemy below to 0, die. There is some probability to drop an item.
protected override void Die()
{
SendMessage("DropItem");
lm.killEnemyNum++;
GameObject.Destroy(gameObject);
}
Next turoial please click Make it complete.
More details, please visit the project here