1

I am using unity2019.2.0b with c# langauge.

When i create object and I change properties of object via script like scale rotation position or velocity

In my case is working fine with if-else statement, but I want to use ternary operator because each properties setting per 1 line script for improved readability.

So my question is how can i convert if else statement to ternary operator which doesn't have return value functions

The concept what I want is to check movable is true or not

  • if true then call function1(parameter1)

  • if false then call function2(parameter1)

or

  • if true then call function3(parameter1)

  • if false then call function4(parameter1, parameter2)

all functions are no return value functions.

I want to write like this (movable is boolean)

movable? SetObjectMoving(gameobject) : RemoveComponent<MoveComponent>(gameobject);

this is code when use if-else statement

if(movable)
{
ObjectMovingSystem(gameobject);
}else{
RemoveComponent<MoveComponent>(gameobject);
}

And this is my full code

    private void CreateEntity()
    {

        for (int i = 0; i < spawnCountPerFrame; i++)
        {
            Entity instance = shapeFactory.GetEntityRandom();
            entityManager.SetComponentData<Translation>(instance, new Translation { Value = SpawnZoneOfLevel.SpawnPoint });
            entityManager.SetComponentData<Rotation>(instance, new Rotation { Value = Random.rotation });
            entityManager.SetComponentData<Scale>(instance, new Scale { Value = Random.Range(0.1f, 1f) });
            //(movable ? SetEntityMovement(instance) : RemoveMovementComponent<PersistantObjectMovement>(instance));

            //PersistantObjectmovement
            if (movable)
            {
                SetEntityMovement(instance);
            }
            else
            {
                RemoveMovementComponent<PersistantObjectMovement>(instance);
            }

            //(rotatable ? SetEntityRotation(instance) : RemoveMovementComponent<PersistantObjectRotation>(instance));
            //PersistantObjectRotation
            if (rotatable)
            {
                SetEntityRotation(instance);
            }
            else
            {
                RemoveMovementComponent<PersistantObjectRotation>(instance);
            }


            entityList.Add(instance);
        }
    }


    private void SetEntityMovement(Entity instance)
    {
        entityManager.SetComponentData(instance, new PersistantObjectMovement
        {
            direction = Random.onUnitSphere,
            speed = Random.Range(0.5f, 1)
        });
    }
    private void SetEntityRotation(Entity instance)
    {
        entityManager.SetComponentData(instance, new PersistantObjectRotation
        {
            angularVelocity = Random.onUnitSphere * Random.Range(0f, 90f),
            radiantPerSecond = math.radians(Random.Range(120f, 360f))
        });
    }

    private void RemoveMovementComponent<T>(Entity instance) where T : IComponentData
    {
        entityManager.RemoveComponent(instance, typeof(T));
    }

I know this is not really necessary to do, but i want to know there is anyway to do if-else statement write 1 line like ternary operator?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Natejin
  • 55
  • 9
  • There is no such thing as "trinary" operator – Vidmantas Blazevicius Aug 02 '19 at 09:36
  • 1
    I don't think you can do that. Closest is `if (movable) X(); else Y();` – kovac Aug 02 '19 at 09:42
  • That's my bad. I don't know why i write trinary... its ternary operator – Natejin Aug 02 '19 at 09:43
  • 1
    Maybe this will help https://stackoverflow.com/questions/5490095/method-call-using-ternary-operator .. however, it's mis-using the operator and isn't really any better than what you have. – steve16351 Aug 02 '19 at 09:46
  • I already read that case. That case is good when function 1 and 2 has same parameter so Action will be work for it. But i try it in my case and not working... – Natejin Aug 02 '19 at 09:52
  • @Natejin you can adapt it to `(a == b ? new Action(() => doThis(1)) : doThat)();` to add a parameter to one or both. – steve16351 Aug 02 '19 at 09:56
  • @steve16351 this is what i want it i write `(movable ? new Action(() => SetEntityMovement(instance)) : new Action(() => RemoveMovementComponent(instance)))();` and its work Thank you – Natejin Aug 02 '19 at 10:01
  • You can make it a little bit neater like `(movable ? (Action)SetEntityMovement : RemoveComponent)(instance);` as both method signatures are the same – steve16351 Aug 02 '19 at 10:13
  • @steve16351 Oh this is much better than before you gave it thank you. – Natejin Aug 02 '19 at 10:20

4 Answers4

1

@steve16351 gave good idea for me.

Use ternary operator with 1 line what i want it.

        Entity instance = shapeFactory.GetEntityRandom();
        entityManager.SetComponentData<Translation>(instance, new Translation { Value = SpawnZoneOfLevel.SpawnPoint });
        entityManager.SetComponentData<Rotation>(instance, new Rotation { Value = Random.rotation });
        entityManager.SetComponentData<Scale>(instance, new Scale { Value = Random.Range(0.1f, 1f) });
        (movable ? (Action<Entity>)SetEntityMovement : RemoveMovementComponent<PersistantObjectMovement>)(instance);
        (rotatable ? (Action<Entity>)SetEntityRotation : RemoveMovementComponent<PersistantObjectRotation>)(instance);

How about you guys think with this code?

Natejin
  • 55
  • 9
0

I guess this qualifies :P

if (movable) SetEntityMovement(instance); else RemoveMovementComponent<PersistantObjectMovement>(instance);

I don't think there's a ternary style operator for this. I would probably just go with the normal if-else with braces.

kovac
  • 4,945
  • 9
  • 47
  • 90
0

I think you mean ternary operator not trinary operator.

Ternary operators are there to return a value, if you are not useing them to return a value you are abusing them. In otherwords if someone reading your code sees a ternary operator he can expect the operation to return a value.

If you use the ternary operator instead of an if statement just to conditionally execute code you are making the code less readable not more readable.

The reason this does not work is because the ternary operator needs to know the return type to be able to compile. It does this by looking at the return types of the clauses following the '?'. void methods do not have a return type and so compilation of the ternary operator will fail attempting to get the return type.

symaps
  • 62
  • 6
  • My bad, its ternary operator like you said. So i can not use ternary operator for my case.. – Natejin Aug 02 '19 at 09:49
  • you could hack it but not a good idea you would be making the code much less readable. On a side note codereadability is really not about having fewer lines of code but rather having the most understandable and concise way of expressing the action of the code. Breaking code over multiple lines can make the code much more readable even though it adds to the number of lines of code. – symaps Aug 02 '19 at 09:57
  • I cannot comment on the accepted answer as I don't yet have reputation of 50. However the accepted answer is the hack I was talking about, it is not a good idea. It hides the intent of the code in question. using an if block clearly states the intention of the code the ternary operator is to return a result. If the problem is a nail put down the screwdriver. Good code should be clear to understand, coercing code into using constructs like the accepted answer obfuscates the intent of the code. – symaps Aug 12 '19 at 15:07
0

If you really want to do it you can use:

(movable ? (Action<bool>)SetEntityMovement : RemoveMovementComponent<PersistantObjectMovement>)(instance)
Human
  • 67
  • 1
  • 3