0

I have a problem with my bool value that I dont understand. I have an Actions script, which derives from MonoBehavior. In that script I have a bool variable "IsCompleted", which shall indicate whether an Attack is finished or not. In Awake there I set this bool to true, to indicate that no attack is running. In another Script - ScriptableAttack - which derives from ScriptableObject, I have a function that is the main part of an attack. There I edit this value and set it to false. Then, if conditions are good, I want to run a timer after that the bool is set to false again. Now, since I can't use the typical Update method on a ScriptableObject, I want to check if this value is false in a third script I have - CharacterSettings - which derives from MonoBehavior. The problem now is that when I check that value on Update in the CharacterSettings script, it always returns true, while I see that it is indeed false within ScriptableAttack. I also checked if I overwrite this value somewhere but couldn't find anyhing. The usages I wrote down here are the only ones I have in my application. Maybe somebody can help or at least explain this behavior to me.

Here's the base of the ScriptableObjects function:

        public void Attack()
        {
            if (!_actions.IsCompleted)
            {
                return;
            }

            _actions.IsCompleted = false;

            if (Vector3.Distance(GeneralGameManager.Characters[0].transform.position,
                    GeneralGameManager.Characters[1].transform.position) > _attackDistance)
            {
                _actions.IsCompleted = true;
                return;
            }
        }

Further description: Actions is a script which basically holds the SOs and the IsCompleted bool. It looks like this:

        [SerializeField] private ScriptableAttack _frontPunch;
        [SerializeField] private ScriptableAttack _backPunch;
        [SerializeField] private ScriptableAttack _frontKick;
        [SerializeField] private ScriptableAttack _backKick;
        [HideInInspector] public ScriptableAttack[] AttackCollection;
        [HideInInspector] public bool IsCompleted;

        private void Awake()
        {
            IsCompleted = true;

            AttackCollection = new[] {FrontPunch, BackPunch, FrontKick, BackKick};
        }

The CharacterSettings Script is a script that each fighter (there are two of them) has attached. There I would like to do something like this:

        private void Update()
        {
            if (_actions.IsCompleted)
            {
                return;
            }

            timer += Time.deltaTime;

            if (timer >= attackExecutionTimer)
            {
                //Do damage and stuff
                _actions.IsCompleted = true;
                timer = 0;
            }
        }

Where timer is a float value at 0 and attackExecutionTimer is a float parameter set in the SOs.

Attack() from the SO is called on Input.GetKeyDown.

  • 1
    I doubt you know the purpose of scriptable objects(SO). You shouldn't use SO for data transferring or try to change variable of SO at runtime. SO deserialized in Unity Editor and Unity GamePlay time. But when you build your project, your SOs will be serialized and you won't be able to change value of it just get it (READONLY). Use a C# class for data transferring not serialized object. – SeLeCtRa Jan 21 '21 at 14:55
  • So this doesn't work in general? Here I use a SO because I have 4 attacks which are all executed the same but with different parameters. Therefore I found a solution with SO quite fitting. The variable I change there is not of the SO because of what you meant. – Fledermauserl Jan 21 '21 at 15:00
  • 1
    Please add a [minimal reproducible code example](https://stackoverflow.com/help/minimal-reproducible-example) – derHugo Jan 21 '21 at 15:01
  • SO is not magical object. It is just simple serialized data container. If you have a lot of skill, item, character etc create SO for it and from that data you can create object. We have no idea about your code but if you have only 4 attack and many similarities just create base class that contains similar property and methods then in child class inherit this class. If you want to expand this system, create scriptable object but don't interact with it. Just get data from it and assign data to your main class. [Scriptable Obj](https://learn.unity.com/tutorial/introduction-to-scriptable-objects) – SeLeCtRa Jan 21 '21 at 15:06
  • I added some code and I would really love to use the ScriptableObject solution. – Fledermauserl Jan 21 '21 at 15:21
  • please include how exactly you use the SO, where does `_actions` come from? How/Where is `Attack` called? – derHugo Jan 21 '21 at 15:32
  • Ok, I added again some code. This should be everything involved. – Fledermauserl Jan 21 '21 at 16:34
  • 1
    OP still we don't have enough information. I got what you want and what is the problem but important part why you change Attack part and variable value change process in SO class? You have reference to all scriptable objects already. Just use this method in your non-SO class. Then there shouldn't be any problem. You can still use SO objects too. Also I suggest to use a base class for your SO so you can reuse variables. In this way you can speed up the creation process and instead of reference every SO class name you just reference base class and when necessary cast as child class – SeLeCtRa Jan 21 '21 at 19:07
  • So wait .. you say `Attack` is in the SO but you are accessing `_actions` there .. may I ask how exactly you assign `_actions`? Is this maybe a prefab and therefore never changes since it is not part of the scene? ... Please read again how to create a **complete and reproducible** code example .. with all code necessary for reproducing the issue. Currently we can not reproduce the behavior – derHugo Jan 21 '21 at 20:47

0 Answers0