Equipping and activating energy sword blade?

zoicelols

Member
1573156410984.png

1573156454416.png

I have an energy sword weapon like in star wars with a retractable blade set on a bool and this is what I'm trying to accomplish.

I want to make it so that my character starts the game with it holstered and the blade is retracted. When my character uses an attack, it will be pulled from the holster and then the blade will come out, but when the character hasn't attacked within a specific time, ill say 5 seconds, then it will retract and be holstered again. So like if my character runs and doesn't attack for that amount of time or just sits idle for that time.

This is the code. I also am wondering how to connect the equip action with activate saber and unequipped action with deactivate saber through code while also accomplishing when and how I specified above.




Code:
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace GlowingSwords.Scripts
{
    /// <inheritdoc />
    /// <summary>
    /// This script is used to control the glowing sword weapon. It is used to set the colors, deactivate, activate and more.
    /// </summary>
    [ExecuteInEditMode]
    public class GlowingSword : MonoBehaviour {
        #region Private Members
        
        #region Serializable
        
        [Tooltip("Truth value which indicates whether the glowing sword is active or inactive.")]
        [SerializeField]
        private bool saberActive = true;

        private bool _lastSaberActiveStatus;
        
        [Tooltip("The color of the glowing sword")]
        [SerializeField]
        private Color bladeColor = Color.red;
        
        #endregion
        
        /// <summary>
        /// List of blades which hang as child in the object.
        /// </summary>
        private List<GlowingSwordBlade> _blades;

        private Color _lastColor;

        #endregion

        #region Public Serializable Members

        [Tooltip("The speed at which the blade is retracted or extended when the glowing sword is activated or deactivated.")]
        public float BladeExtendSpeed = 0.4f;
        
        #endregion

        #region Properties

        /// <summary>
        /// Allows you to change the color of the glowing sword.
        /// If the color is changed, the glowing sword is updated.
        /// </summary>
        public Color BladeColor
        {
            get { return bladeColor; }
            set
            {
                bladeColor = _lastColor = value;
                UpdateLightSaber();
            }
        }
        
        /// <summary>
        /// Enables or disables the glowing sword.
        /// If the status is changed, the
        /// glowing sword is updated.
        /// </summary>
        public bool SaberActive
        {
            get { return saberActive; }
            set
            {
                if (saberActive.Equals(value)
                    && _lastSaberActiveStatus == saberActive)
                    return;

                _lastSaberActiveStatus = saberActive = value;
                UpdateLightSaber();
            }
        }
        
        #endregion

        #region Setup
        // Use this for initialization
        private void Awake ()
        {
            if (FindSetupBlades())
                return;

            Setup();
        }

        private void LateUpdate()
        {
            if (Time.frameCount % 3 != 0)
                return;
            
            
            if (_lastSaberActiveStatus != saberActive)
                SaberActive = saberActive;

            if (_lastColor != bladeColor)
                BladeColor = bladeColor;
        }

        /// <summary>
        /// Find and setup light saber children blades
        /// </summary>
        /// <returns></returns>
        private bool FindSetupBlades()
        {
            _blades = gameObject.FindChildrenByType<GlowingSwordBlade>();
            if (_blades != null && _blades.Any())
                return false;
            
            Debug.LogWarning("No light saber blades found. " +
                             $"Please add some blade children by adding a {nameof(GlowingSwordBlade)} script." +
                             $"The light saber Must have at least 1 blade.");
            return true;
        }

        /// <summary>
        /// Setup for the light saber
        /// </summary>
        private void Setup()
        {
            //Execute setup for the blades of the light saber.
            _blades.ForEach(x => x.Setup(BladeExtendSpeed, SaberActive));

            UpdateLightSaber();
        }
        #endregion

        #region Updates

        /// <summary>
        /// Updates the color of the blades.
        /// </summary>
        private void UpdateColor()
        {
            bladeColor.a = Mathf.Clamp(bladeColor.a, 0.1f, 1f);
            
            //Update each blade
            _blades?.ForEach(x=>x.Color=bladeColor);
        }

        /// <summary>
        /// Updates each blade.
        /// It updates the active status, the light and the saber size.
        /// </summary>
        private void UpdateBlades()
        {
            _blades?.ForEach(glowingSwordBlade =>
            {
                glowingSwordBlade.BladeActive = SaberActive;
                glowingSwordBlade.UpdateLighting();
                glowingSwordBlade.UpdateSaberSize();
            });
        }

        /// <summary>
        /// This method updates the color of the glowing sword and its blades.
        /// </summary>
        public void UpdateLightSaber()
        {
            // Setup the color of the light saber.
            UpdateColor();

            // initially update blade length, so that it isn't set to what we have in unity's visual editor
            UpdateBlades();
        }

        #endregion

        #region Toggle

        /// <summary>
        /// Toggle for activating deactivating the glowing sword.
        /// </summary>
        public void ToggleActive()
        {
            SaberActive = !SaberActive;
        }

        #endregion
    }
}
 
Within the character controller you can use EquipUnequip.StartEquipUnequip to equip or unequip the specified item index. When you call this method you can then also activate or deactivate your blade.

If you don't want to manually call StartEquipUnequip you can listen for the OnItemActivated event to activate or deactivate the blade.
 
Within the character controller you can use EquipUnequip.StartEquipUnequip to equip or unequip the specified item index. When you call this method you can then also activate or deactivate your blade.

If you don't want to manually call StartEquipUnequip you can listen for the OnItemActivated event to activate or deactivate the blade.
Could you please clarify how to use OnItemActivated?
The OnCharacterItemAbilityActive event just gives this:
Opsive.UltimateCharacterController.Character.Abilities.Items.EquipUnequip activated: True
 
On that page it contains an example script for registering for the event so you can use it. Is there something in particular that you are looking for?
 
I want to apply some effects on equip and unequip, e.g. shield appears and disappears magically. For now I copied an animator from Shield Bubble. However, I'd like to add more effects, e.g. particles.
Regarding OnItemActivated, I am not sure how to use it, what parameters should be used. I was unable to find a proper article or forum thread.
Any examples would be really helpful.
 
In that case it would be easier to listen for the OnInventoryEquipItem event:

Code:
        EventHandler.RegisterEvent<Item, int>(character, "OnInventoryEquipItem", OnEquipItem);

        /// <summary>
        /// An item has been equipped.
        /// </summary>
        /// <param name="item">The equipped item.</param>
        /// <param name="slotID">The slot that the item now occupies.</param>
        private void OnEquipItem(Item item, int slotID)
        {

        }

        EventHandler.UnregisterEvent<Item, int>(character, "OnInventoryEquipItem", OnEquipItem);

You can then match the ItemType to determine if the effects should be equipped. There is a similar event for when the item is unequipped.
 
In that case it would be easier to listen for the OnInventoryEquipItem event:

You can then match the ItemType to determine if the effects should be equipped. There is a similar event for when the item is unequipped.

And how the visible object can be accessed? Should it work?
Code:
item.GetComponent<PerspectiveItem>();
// or
item.GetComponent<Items.ThirdPersonPerspectiveItem>()
 
Last edited:
It looks like this one is correct
Code:
item.GetComponent<ThirdPersonPerspectiveItem>().Object
 
I now got a question regarding the Unequip event.
I play an animation that scales the item from zero to a specific size during the OnEquip event which works fine.
However, when I play another animation that does opposite during the OnUnequip event, nothing happens, the item simply disappears.
Is there any method to override/delay it?
 
When the item is unequipped from the inventory then it will be deactivated. If you derive the Item or ItemAction class you could override the StartUnequip/Unequip events. There isn't a corresponding event which gets sent for these type of callbacks.
 
Top