Create an Ability System with Scriptable Objects

using UnityEngine;
using System.Collections;

public abstract class Ability : ScriptableObject {

    public string aName = "New Ability";
    public Sprite aSprite;
    public AudioClip aSound;
    public float aBaseCoolDown = 1f;

    public abstract void Initialize(GameObject obj);
    public abstract void TriggerAbility();
}
using UnityEngine;
using System.Collections;

[CreateAssetMenu (menuName = "Abilities/RaycastAbility")]
public class RaycastAbility : Ability {

    public int gunDamage = 1;
    public float weaponRange = 50f;
    public float hitForce = 100f;
    public Color laserColor = Color.white;

    private RaycastShootTriggerable rcShoot;

    public override void Initialize(GameObject obj)
    {
        rcShoot = obj.GetComponent<RaycastShootTriggerable> ();
        rcShoot.Initialize ();

        rcShoot.gunDamage = gunDamage;
        rcShoot.weaponRange = weaponRange;
        rcShoot.hitForce = hitForce;
        rcShoot.laserLine.material = new Material (Shader.Find ("Unlit/Color"));
        rcShoot.laserLine.material.color = laserColor;

    }

    public override void TriggerAbility()
    {
        rcShoot.Fire ();
    }


}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class AbilityCoolDown : MonoBehaviour {

    public string abilityButtonAxisName = "Fire1";
    public Image darkMask;
    public Text coolDownTextDisplay;

    [SerializeField] private Ability ability;
    [SerializeField] private GameObject weaponHolder;
    private Image myButtonImage;
    private AudioSource abilitySource;
    private float coolDownDuration;
    private float nextReadyTime;
    private float coolDownTimeLeft;


    void Start () 
    {
        Initialize (ability, weaponHolder);    
    }

    public void Initialize(Ability selectedAbility, GameObject weaponHolder)
    {
        ability = selectedAbility;
        myButtonImage = GetComponent<Image> ();
        abilitySource = GetComponent<AudioSource> ();
        myButtonImage.sprite = ability.aSprite;
        darkMask.sprite = ability.aSprite;
        coolDownDuration = ability.aBaseCoolDown;
        ability.Initialize (weaponHolder);
        AbilityReady ();
    }

    // Update is called once per frame
    void Update () 
    {
        bool coolDownComplete = (Time.time > nextReadyTime);
        if (coolDownComplete) 
        {
            AbilityReady ();
            if (Input.GetButtonDown (abilityButtonAxisName)) 
            {
                ButtonTriggered ();
            }
        } else 
        {
            CoolDown();
        }
    }

    private void AbilityReady()
    {
        coolDownTextDisplay.enabled = false;
        darkMask.enabled = false;
    }

    private void CoolDown()
    {
        coolDownTimeLeft -= Time.deltaTime;
        float roundedCd = Mathf.Round (coolDownTimeLeft);
        coolDownTextDisplay.text = roundedCd.ToString ();
        darkMask.fillAmount = (coolDownTimeLeft / coolDownDuration);
    }

    private void ButtonTriggered()
    {
        nextReadyTime = coolDownDuration + Time.time;
        coolDownTimeLeft = coolDownDuration;
        darkMask.enabled = true;
        coolDownTextDisplay.enabled = true;

        abilitySource.clip = ability.aSound;
        abilitySource.Play ();
        ability.TriggerAbility ();
    }
}
using UnityEngine;
using System.Collections;

[CreateAssetMenu (menuName = "Abilities/ProjectileAbility")]
public class ProjectileAbility : Ability {

    public float projectileForce = 500f;
    public Rigidbody projectile;

    private ProjectileShootTriggerable launcher;

    public override void Initialize(GameObject obj)
    {
        launcher = obj.GetComponent<ProjectileShootTriggerable> ();
        launcher.projectileForce = projectileForce;
        launcher.projectile = projectile;
    }

    public override void TriggerAbility()
    {
        launcher.Launch ();
    }

}
using UnityEngine;
using System.Collections;

public class RaycastShootTriggerable : MonoBehaviour {

    [HideInInspector] public int gunDamage = 1;                            // Set the number of hitpoints that this gun will take away from shot objects with a health script.
    [HideInInspector] public float weaponRange = 50f;                    // Distance in unity units over which the player can fire.
    [HideInInspector] public float hitForce = 100f;                        // Amount of force which will be added to objects with a rigidbody shot by the player.
    public Transform gunEnd;                                            // Holds a reference to the gun end object, marking the muzzle location of the gun.
    [HideInInspector] public LineRenderer laserLine;                    // Reference to the LineRenderer component which will display our laserline.

    private Camera fpsCam;                                                // Holds a reference to the first person camera.
    private WaitForSeconds shotDuration = new WaitForSeconds(.07f);        // WaitForSeconds object used by our ShotEffect coroutine, determines time laser line will remain visible.


    public void Initialize ()
    {
        //Get and store a reference to our LineRenderer component
        laserLine = GetComponent<LineRenderer> ();

        //Get and store a reference to our Camera
        fpsCam = GetComponentInParent<Camera> ();
    }

    public void Fire()
    {

        //Create a vector at the center of our camera's near clip plane.
        Vector3 rayOrigin = fpsCam.ViewportToWorldPoint (new Vector3 (.5f, .5f, 0));

        //Draw a debug line which will show where our ray will eventually be
        Debug.DrawRay (rayOrigin, fpsCam.transform.forward * weaponRange, Color.green);

        //Declare a raycast hit to store information about what our raycast has hit.
        RaycastHit hit;

        //Start our ShotEffect coroutine to turn our laser line on and off
        StartCoroutine(ShotEffect());

        //Set the start position for our visual effect for our laser to the position of gunEnd
        laserLine.SetPosition(0, gunEnd.position);

        //Check if our raycast has hit anything
        if (Physics.Raycast(rayOrigin,fpsCam.transform.forward, out hit, weaponRange))
        {
            //Set the end position for our laser line 
            laserLine.SetPosition(1, hit.point);

            //Get a reference to a health script attached to the collider we hit
            ShootableBox health = hit.collider.GetComponent<ShootableBox>();

            //If there was a health script attached
            if (health != null)
            {
                //Call the damage function of that script, passing in our gunDamage variable
                health.Damage (gunDamage);
            }

            //Check if the object we hit has a rigidbody attached
            if (hit.rigidbody != null)
            {
                //Add force to the rigidbody we hit, in the direction it was hit from
                hit.rigidbody.AddForce (-hit.normal * hitForce);
            }
        }
        else
        {
            //if we did not hit anything, set the end of the line to a position directly away from
            laserLine.SetPosition(1, fpsCam.transform.forward * weaponRange);
        }
    }

    private IEnumerator ShotEffect()
    {

        //Turn on our line renderer
        laserLine.enabled = true;
        //Wait for .07 seconds
        yield return shotDuration;

        //Deactivate our line renderer after waiting
        laserLine.enabled = false;
    }
}
using UnityEngine;
using System.Collections;

public class ProjectileShootTriggerable : MonoBehaviour {

    [HideInInspector] public Rigidbody projectile;                            // Rigidbody variable to hold a reference to our projectile prefab
    public Transform bulletSpawn;                            // Transform variable to hold the location where we will spawn our projectile
    [HideInInspector] public float projectileForce = 250f;                    // Float variable to hold the amount of force which we will apply to launch our projectiles

    public void Launch()
    {
        //Instantiate a copy of our projectile and store it in a new rigidbody variable called clonedBullet
        Rigidbody clonedBullet = Instantiate(projectile, bulletSpawn.position, transform.rotation) as Rigidbody;

        //Add force to the instantiated bullet, pushing it forward away from the bulletSpawn location, using projectile force for how hard to push it away
        clonedBullet.AddForce(bulletSpawn.transform.forward * projectileForce);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值