UNITY3D – FPS TUTORIÁL – [9] – PŘÍPRAVA INVENTÁŘE PART #4


Tentokrát si uděláme

  • Konečně funkční měnění zbraní s pár chybkami



Celý projekt je ke stažení zde.

Už jen jeden bug od prakticky funkčního zbraňového systému.

Looplist.cs

using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
using System.Collections.ObjectModel;

public class LoopList<T>
{
    public static LoopList<T> New(params T[] items)
    {
        if (items == null)
            throw new ArgumentNullException();

        return new LoopList<T>(items.ToList());
    }
    public LoopList()
    {
        this.Items = new List<T>();
    }
    public LoopList(IEnumerable<T> items)
    {
        if (items == null)
            throw new ArgumentNullException();

        var a = items.ToList();

        this.Items = a;
    }

    public T Current
    {
        get
        {
            if (Items == null || Items.Count == 0)
                return default(T);
            return Items[Position];
        }
        set { Position = Items.IndexOf(value); }
    }
    
    int position;
    public int Position
    {
        get
        {
            if (Items == null)
                throw new NullReferenceException("The collection is null.");
            if (Items.Count == 0)
                throw new Exception("The collection is empty.");

            if (position >= Items.Count)
                position = 0;
            else if (position < 0)
                position = Items.Count - 1;

            return position;
        }
        set
        {
            if (Items == null)
                throw new NullReferenceException("The collection is null.");
            if (Items.Count == 0)
                throw new Exception("The collection is empty.");

            if (value >= Items.Count)
                position = 0;
            else if (value < 0)
                position = Items.Count - 1;
            else
                position = value;
        }
    }
    protected System.Random rand;

    public IEnumerable<T> Random(int amount)
    {
        if (rand == null)
            rand = new System.Random();

        for (int i = 0; i < amount; i++)
            yield return Random();
    }
    public T Random()
    {
        if (rand == null)
            rand = new System.Random();

        Position = rand.Next(Items.Count);
        return Next();
    }
    public IEnumerable<T> Next(int amount)
    {
        for (int i = 0; i < amount; i++)
            yield return Next();
    }
    public T Next()
    {
        ++Position;
        return Items[Position];
    }

    public IEnumerable<T> Previous(int amount)
    {
        for (int i = 0; i < amount; i++)
            yield return Previous();
    }
    public T Previous()
    {
        --Position;
        return Items[Position];
    }

    public IList<T> Items { get; protected set; }

    public ReadOnlyCollection<T> GetReadonlyItems()
    {
        return Items.ToList().AsReadOnly();
    }
}

Inventory.cs

using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Inventory<T>
{
    LoopList<T> list = new LoopList<T>();
    public void Add(T item)
    {
        list.Items.Add(item);
    }
    public void Next()
    {
        list.Next();
    }
    public void Previous()
    {
        list.Previous();
    }

    public T CurrentItem
    {
        get
        {
            return list.Current;
        }
        set
        {
            list.Current = value;
        }
    }
}

WeaponStorageController.cs

using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class WeaponStorageController : MonoBehaviour
{
    [SerializeField]
    Weapon pistol;
    [SerializeField]
    Weapon machinegun;

    public static Weapon Pistol;
    public static Weapon Machinegun;

    void Start()
    {
        Pistol = pistol;
        Machinegun = machinegun;
    }
}

Shooter.cs

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

public class Shooter : MonoBehaviour {

    public Transform RayCastSpot, WeaponSpot;
    RaycastHit hitObject;

    float nextFire = 0;

    Inventory<WeaponData> inventory = new Inventory<WeaponData>();
    Weapon currWep;

    void Start()
    {
        inventory.Add(WeaponStorageController.Pistol.Data);
        inventory.Add(WeaponStorageController.Machinegun.Data);
        SelectWeapon();
    }
	void Update ()
    {
	    if(Input.GetKey(KeyCode.Mouse0) && Time.time > nextFire)
        {
            nextFire = Time.time + currWep.Data.FireRate;
            currWep.Shoot(RayCastSpot);
        }
        if(Input.GetKeyDown(KeyCode.R))
        {
            currWep.Reload();
        }
        if(Input.GetKeyDown(KeyCode.E))
        {
            inventory.Next();
            SelectWeapon();
        }
        if (Input.GetKeyDown(KeyCode.Q))
        {
            inventory.Previous();
            SelectWeapon();
        }
    }

    void SelectWeapon()
    {
        if (currWep != null)
            DestroyWeapon();
        InitializateWeapon();
    }

    void DestroyWeapon()
    {
        Destroy(currWep.gameObject);
    }
    void InitializateWeapon()
    {
        var currentData = inventory.CurrentItem;
        currWep = Instantiate(inventory.CurrentItem.Model);
        currWep.Data = currentData;

        currWep.transform.parent = WeaponSpot;
        currWep.transform.localPosition = Vector3.zero;
        currWep.transform.localRotation = Quaternion.identity;

        UIController.MagazineValueUI.text = "Magazines: " + currWep.Data.magazines;
        UIController.AmmoValueUI.text = "Ammo: " + currWep.Data.ammo;
    }

    // Znicit starou zbran

    // Vytvorit novou zbran

}

ShootebleWeapon.cs

using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class ShootebleWeapon : Weapon
{
    RaycastHit hitObject;
    public override void Shoot(Transform rayCastSpot)
    {
        if (Data.ammo <= 0)
        {
            return;
        }
        Data.ammo--;
        UIController.AmmoValueUI.text = "Ammo: " + Data.ammo;

        float offsetX = UnityEngine.Random.Range(-Data.Accuracy, Data.Accuracy);
        float offsetZ = UnityEngine.Random.Range(-Data.Accuracy, Data.Accuracy);
        float offsetY = UnityEngine.Random.Range(-Data.Accuracy, Data.Accuracy);

        Vector3 direction = new Vector3(rayCastSpot.forward.x + offsetX,
                                        rayCastSpot.forward.y + offsetY,
                                        rayCastSpot.forward.z + offsetZ);

        bool hit = Physics.Raycast(rayCastSpot.position, direction, out hitObject, 1000, Data.Mask);

        GameObject shot = MonoBehaviour.Instantiate(ShotStorageController.Shot) as GameObject;
        LineRenderer lineRenderer = shot.GetComponent<LineRenderer>();
        lineRenderer.SetPosition(0, FireSpot.position);
        if (hit == true)
        {
            lineRenderer.SetPosition(1, hitObject.point);

            Quaternion objRot = Quaternion.FromToRotation(Vector3.up, hitObject.normal);
            GameObject bHole = MonoBehaviour.Instantiate(BulletHoleController.ChooseHole(hitObject.transform.gameObject.layer), hitObject.point, objRot) as GameObject;
            //bHole.transform.SetParent(hitObject.transform);
            //bHole.transform.localScale = Vector3.one;
            MonoBehaviour.Destroy(bHole, 10);
        }
        else if (hit == false)
        {
            lineRenderer.SetPosition(1, rayCastSpot.forward * 1000);
        }
    }
    public override void Reload()
    {
        if (Data.ammo != Data.MagazineCapacity && !(Data.magazines <= 0))
        {
            Data.ammo = Data.MagazineCapacity;
            Data.magazines--;
            UIController.MagazineValueUI.text = "Magazines: " + Data.magazines;
        }
    }
}

Weapon.cs

using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public abstract class Weapon : MonoBehaviour
{
    [SerializeField]
    public WeaponData Data;
    public Transform FireSpot;

    abstract public void Shoot(Transform rayCastSpot);
    abstract public void Reload();
}

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *