#archived-code-general

1 messages · Page 212 of 1

hard viper
#

destroyed objects == null, but you could still (for example) call myDictionary[myDeadObject], and it would not throw an error iirc

pearl ice
#

? won't work in this case because you are trying to get a nullable component by adding it

thick socket
#

good to know thanks

#

Its easy enough in my case because I only need to grab it in 1 case where it wont be null anyway

#
if(attackType == AttackType.sniper)
        {
            laser = fighter.GetComponent<LookAtEnemy>().laser.gameObject;
        }
hard viper
#
  1. If component NEEDS to be there
    x = GetComponent, then Debug.Assert( x!= null, “Couldn’t find component!”);
#
  1. If component is optional,
    if ( TryGetComponent( out x))
    so you have separate logic for if you can and can’t find the component
thick socket
#

totally forgot TryGetComponent existed

hard viper
#

trygetcomponent is a bit lighter if false because you don’t need to get something for the out parameter

#

but those are the two main patterns I always use

#

Get and assert, or if tryget

naive swallow
#

I'm trying to detect if two line renderers overlap. Due to the data I'm parsing into a line renderer, it's possible that the data I'm getting could cause two identical lines to be drawn. Is there a better way to do this than to loop through all the points of a line renderer against all of the points in another line renderer, and seeing if they match?

#

Oh, I should also note: The lines I'm drawing might be identical, but in a different order. They're closed polygons so the starting point could be anywhere in the shape, so I can't just compare index 0 to 0 and so on

leaden ice
#

sort by x then tiebreak with y for example?

naive swallow
#

I'm not sure if the time cost of the sorting outweighs the extra time spent checking unnecessary nodes though...

leaden ice
#

Wait are we looking for an overlap? or for identical drawings?

#

and actually sorting the points doesn't quite work for identical drawing detection because you can draw many different pictures with the same points by changing which points connect to which other points 🤔

#

it's more the edges/lines you'd have to sort and compare

heady iris
#

So are you only trying to detect when two line renderers have the same points and draw the same shape?

#

i.e. they have the points in the same order, modulo a circular shift

#

0123 and 1230 are a match

naive swallow
# leaden ice Wait are we looking for an overlap? or for identical drawings?

So, basically, I have polygons defined by a list of points in a file generated by another program. I'm consuming that output and making shapes with it. The shapes are closed polygons, but the output could contain multiple overlapping shapes. They'd have all the same points, but whichever one is the "start" might be different. Imagine two squares, one of them is (1, 0), (1, 1), (0, 1), (0, 0) and the other is (0, 1), (0, 0), (1, 0), (1, 1). They're the same square, so I don't want two line renderers drawing it

leaden ice
#

I see it the other way around 😉

leaden ice
naive swallow
#

Yeah

fervent furnace
#

three scans+hash table

leaden ice
#

then you can compare the shapes point by point to see if they're identical

#

you basically slice at the small point and reconnect the two sublists

naive swallow
#

Does that actually save any time over just iterating over both lists?

leaden ice
#

you still have to iterate

fervent furnace
#

idk why the first thing comes to my mind is binary search, until i realize that O(n) is must since you have to check if all the points are same and ordered

leaden ice
#

You will have to iterate over each list at least once in every case

#

There are fastish ways to tell that they are definitely NOT the same shape

rigid island
#

how many times you gonna ask this

leaden ice
#

e.g.:

  • different number of points
  • HashSet.IntersectWith the other set is the same as the set.
spring creek
#

That is kind of an off-topic question. Especially with how many times you've asked it

#

Well 🤷‍♂️ find a server with a channel you can do that in. Cause this one aint that

mighty wing
#

What is difference with
Debug.Log("Value: " + value);
and
Debug.Log($"Value: {value}"); ?

leaden ice
#

it's just more convenient usually to write things inline like that

#

imagine:

string s = "I have " + apples " apples and " + bananas + " bananas";```
Compared to:
```cs
string s = $"I have {apples} apples and {bananas} bananas";```
heady iris
#

The latter is called "string interpolation".

leaden ice
#

it's just much cleaner / easier to read

heady iris
#

It does require you to know exactly what the format string will look like at compile time, though

#

Probably not an issue for you, though

mighty wing
#

Where would string interpolation be an issue?

leaden ice
#

pretty sure it's faster than the repeated + concatenation too when there are multiple dynamic bits of information

mighty wing
#

Yeah that makes sense, thanks all!

hybrid turtle
#

hi I wrote this script to smoothly interchange the positions of two gameObjects

#
    {
        cachedPositions.Add(flipModel, flipModel.transform.position); // add first cached pos 
        cachedPositions.Add(foldModel, foldModel.transform.position); // add second cached pos 
        currentObject = this.gameObject; // get ref to current obj 
    }

    private GameObject GetActiveClicked() // returns the active model not too difficult 
    {
        if (flipModel.Equals(currentObject))
        {
            return flipModel; 
        }
        else 
        {
            return foldModel; 
        }
    }

    private IEnumerator MovePositions(float duration)
    {   float elapsedTime = 0f; 
        Vector3 temp = cachedPositions[GetActiveClicked()]; // retrieve the active clicked 
        if (flipModel.Equals(GetActiveClicked()))
        {
            cachedPositions[GetActiveClicked()] = foldModel.transform.position; // swap the positions 
            foldModel.transform.position = temp; 
        }
        else 
        {
            cachedPositions[GetActiveClicked()] = flipModel.transform.position; 
            flipModel.transform.position = temp; // swap them 
        }

        while(elapsedTime < duration)
        {

            Vector3.MoveTowards(flipModel.transform.position, cachedPositions[flipModel], animationCurve.Evaluate(elapsedTime/duration)); 
            Vector3.MoveTowards(foldModel.transform.position, cachedPositions[foldModel], animationCurve.Evaluate(elapsedTime/duration)); 
            elapsedTime += Time.deltaTime; 
            yield return null; // check why not moving 
        }
    }

    public void OnPointerClick(PointerEventData data)
    {
        StartCoroutine(MovePositions(10f)); // does the time matter 
    }```
#

where cachedPositions is a dictionary

#

it's not swapping and responding instantenously but only one item is moving

leaden ice
#

you're calculating a new position and just discarding it

#

you would need to do something like:
flipModel.transform.position = Vector3.MoveTowards(flipModel.transform.position, cachedPositions[flipModel], animationCurve.Evaluate(elapsedTime/duration));

#

See how in this case we're actually assigning a new position to the object?

hybrid turtle
#

yes i didnt notice that let me now try this

#

ok now it moves one of them moves to whether the other is and stays with it

#

as it moves to the position the other was

#

I used the dictionary to hopefully avoid this issue but idk why it is not working

leaden ice
# hybrid turtle ok now it moves one of them moves to whether the other is and stays with it

well you're immediately doing this at the start of the coroutine:

        if (flipModel.Equals(GetActiveClicked()))
        {
            cachedPositions[GetActiveClicked()] = foldModel.transform.position; // swap the positions 
            foldModel.transform.position = temp; 
        }
        else 
        {
            cachedPositions[GetActiveClicked()] = flipModel.transform.position; 
            flipModel.transform.position = temp; // swap them 
        }```
#

and I'm not sure why exactly

#

I also don't get why it matters which one you clicked. Shouldn't they both be moving in any case?

#

Shouldn't this just be:

cachedPositions[foldModel] = flipModel.transform.position;
cachedPositions[flipModel] = foldModel.transform.position;``` without any if/else and without moving anything right away?
hybrid turtle
#

yeah I mean both are moving at the same time all I wanted to do have a way of keeping track of which one is moving where

hybrid turtle
#

yes so you're right and there is no need for the if else

#

just move it to the position of the other one

leaden ice
#

Also the way you're using the animation curve is quite weird

hybrid turtle
#

yeah I am very unfamiliar with working with them so I took a random guess

#

and tried to compress it bu duration

leaden ice
#

shouldn't it be:

float t = elapsedTime / duration;
t = animationCurve.Evaluate(t);
flipModel.transform.position = Vector3.Lerp(cachedPositions[foldModel], cachedPositions[flipModel], t);
foldModel.transform.position = Vector3.Lerp(cachedPositions[flipModel], cachedPositions[foldModel], t);```
somber tapir
#

Each phone should be responsible to move itself and knowing where to move to

hybrid turtle
#

so @somber tapir separate script attached to each phone?

leaden ice
#

ehhh

#

that sounds way more complicated

#

well not way, but definitely more complicated

hybrid turtle
#

yeah it sounds more complicated @leaden ice i'll give what you put a try

#

it works but does an immediate swap

#

and then does the animation

#
        t = animationCurve.Evaluate(t);
        flipModel.transform.position = Vector3.Lerp(cachedPositions[foldModel], cachedPositions[flipModel], t);
        foldModel.transform.position = Vector3.Lerp(cachedPositions[flipModel], cachedPositions[foldModel], t);```
#

basically what @leaden ice wrote

somber tapir
#

you need to swap the values inside the lerp

#

first the current position, then the target position

hybrid turtle
#

ok yes now how could I continuously keep interchanging them now

#

thats where I wanted to swap the values after the lerp using the dictionary?

#

so that the next time someone clicks on the phone it swaps the other way

leaden ice
#

I think the hardcoding of the two objects here and the dictionary as well are overkill and kind of getting in your way

hybrid turtle
#
    {   
        float elapsedTime = 0f; 
        while(elapsedTime < duration)
        {
            float t = elapsedTime / duration;
            t = animationCurve.Evaluate(t); // evaulate at the animation ccurve 
            flipModel.transform.position = Vector3.Lerp(cachedPositions[flipModel], cachedPositions[foldModel], t); // LERP TO POS1
            foldModel.transform.position = Vector3.Lerp(cachedPositions[foldModel], cachedPositions[flipModel], t); // LERP TO POS2
            elapsedTime += Time.deltaTime;  // increment the time
            yield return null; 
        }
        cachedPositions[flipModel] = flipModel.transform.position; // store position back into dict
        cachedPositions[foldModel] = foldModel.transform.position; 
    }
#

this works you have to update the positions in the dictionary after

#

now my question would be this is a straight path to the other object could I make a curve trajectory path where one phone swings around the other?

leaden ice
#

You can make this agnostic to the objects themselves.

IEnumerator Swap(float duration, Transform a, Transform b, AnimationCurve curve) {
    Vector3 aStart = a.position;
    Vector3 bStart = b.position;

    float elapsedTime = 0;
    while(elapsedTime < duration)
    {
        float t = elapsedTime / duration;
        t = curve.Evaluate(t);
        a.position = Vector3.MoveTowards(aStart, bStart, t); 
        b.position = Vector3.MoveTowards(bStart, aStart, t); 
        elapsedTime += Time.deltaTime; 
        yield return null;
    }
}```
#

then you don't need to worry about the dictionary or swapping anything

#

you can pass any two objects and any curve into this thing and it will swap them according to the curve and their current positions

hybrid turtle
#

yes of course but I want to change the actual motion

#

so that instead of heading straight to the point

#

it traves along a curved path to the point

leaden ice
#

One option is to use a Spline library

#

another option is to use math directly

hybrid turtle
#

like i know parametric equations and that bs

leaden ice
#

for example if you want to make a bunch of assumptions you could treat t as an angle around a circle and position them along the circle using a parametric equation

hybrid turtle
#

i was talking with someone who said I should use two curves to paramterize x and y components of motion

#

but idk if this is a correct approach

leaden ice
#

that's an option too

#

it's not really correct or incorrect, there's a lot of ways to do it.

hybrid turtle
#

but would a spline library make my life a lot easier

#

?

leaden ice
#

uhhh... maybe? 😛

#

It definitely will if you want to make a curve that isn't easily mathematically expressible

hybrid turtle
#

dude i dont want to go back to calc IV

leaden ice
#

or if you don't feel like doing math

hybrid turtle
#

lol yeah i already died doing those things in Calc IV

#

but i mean honestly could be fun

pastel holly
#

What are some good numbers inside a profiler ?

hybrid turtle
#

do you have a specific library recommendation then from Spline?

hybrid turtle
#

thank you so much @leaden ice will take a look and have some fun with it

leaden ice
pastel holly
#

trying to understand waht causes a jolt by profiling but hmm unsure about it

#

especially since most of my high numbers are from universal render pipeline

leaden ice
pastel holly
#

so hard code frame rate into code ?

leaden ice
#

that is not what I said

#

nor is it possible

pastel holly
#

well its a small mobile game so 30-60 limit

#

is all I want

#

and game runs at that smoothly

#

besides that 1 occasional jolt it sometimes gets and thats my issue ThinkSpin

leaden ice
#

ok so profile your game on your target hardware and try to make sure you're getting 60fps

leaden ice
pastel holly
#

cuz its universal render pipeline and 2d physics

#

I dont use any shaders or nothing thats not out of the box

#

and its just 2d project

leaden ice
#

URP is only 0.85ms

pastel holly
#

that doesnt exist on play right ?

#

i mean on build

leaden ice
#

yes

#

it's the editor doing editor things

pastel holly
#

ye I get the jolt outside of editor too

#

thats why Im ignoring that part of log

leaden ice
#

Ok you should try profiling the game on your target hardware in a build then

pastel holly
#

same issue occurs across every platform

#

but ill check it and see how it goes

#

what confuses me is every tutorial I see has so much GC and so much more Time ms and it runs smoothly

lean sail
#

You might just need to turn on incremental gc. For some reason it was off for me by default

main coral
#

Hello im using Unity Gaming Services with Accountname+Password as Authentification. How can I acess the Username with script ? Where is it saved ?

pastel holly
hybrid turtle
#

I dont have access to Splines

#

my project is in Unity 2019.4 😦

leaden ice
hybrid turtle
#

but would it work lol?

leaden ice
#

the problem with slerp is that it will take the shortest path along the surface of a sphere

#

that might or might not be the path you want it to take

#

especially if your two points are on opposite poles of the sphere, the path is kind of undefined

hybrid turtle
#

hmmm yeah but the alternative is using the bezier curve equation is easier than using parametrics

leaden ice
#

if you imagine travelling from the north pole to the south pole of the earth, all lines of longitude are equally valid and equal distance paths

hybrid turtle
#

yes so there's no distinct path

leaden ice
#

I mean I assume Unity will just pick something but it might not be what you want. You could try to goose it a little by starting from slightly off center

hybrid turtle
#

yeah I'll see if I can goof the points a bit

#

and see if it'll magically give me a correct pat h

#

path

#
        float elapsedTime = 0f; 
        while(elapsedTime < duration)
        {
            float t = elapsedTime / duration;
            t = animationCurve.Evaluate(t); // evaulate at the animation ccurve 
            flipModel.transform.position = Vector3.Slerp(cachedPositions[flipModel], cachedPositions[foldModel] - new Vector3(offsetFloat, 0, 0), t); // LERP TO POS1
            foldModel.transform.position = Vector3.Slerp(cachedPositions[foldModel], cachedPositions[flipModel], t); // LERP TO POS2
            elapsedTime += Time.deltaTime;  // increment the time
            yield return null; 
        }
        cachedPositions[flipModel] = flipModel.transform.position; // store position back into dict
        cachedPositions[foldModel] = foldModel.transform.position; 
    }```
#

im thinking something like this make a vector3 and take some x away from it

main coral
#

@leaden ice THANKS that helped me a lot!

fallow obsidian
#

if i do cs PlayerPrefs.Set("email", email); Debug.Log(PlayerPrefs.Get("email")); will this print out the email or do I need to PlayerPrefs.Save() before using Get()? Hmm

leaden ice
#

you do not need to Save

#

Save flushes the changes to disk

fallow obsidian
#

thanks 😄

leaden ice
#

but they are there in memory without a Save

echo quail
#

does someone knows why WebResquest works fine inside editor, but have a different return inside a WebGL build? If so I made a tread in the forum so my code and error is there if someone is willing to help

frozen sun
#

just found out

#

lightdataasset is for the unity editor

#

not engine

lime patrol
#

Hello, WEBGL Audio is not working at open. When i click to canvas it's starting to work. I have this issue. I google it but so many people have that problem. Do you have any ideas to solve it?

unreal temple
#

But I'm not sure, I guess YouTube plays audio without a click

#

Does anyone know if Unity is responsible for creating these?

heady iris
#

Yes.

#

I .gitignore the mono_crash json and blob files

unreal temple
hard viper
#

you guys remember I was talking about a tree structure that was really a graph that's just a bunch of separate trees?

#

turns out, it's just called a forest

unreal temple
heady iris
#

I was surprised those weren’t included

#

Good idea

unreal temple
#

And only one forum thread

#

Maybe give it a 👍 if you can

#

I would probably knock back the PR given the lack of supporting docs

cosmic rain
#

This is very weird. Just to make sure, did you make any changes in project - physics or to the timestep?

scarlet juniper
#

i was making a new movement script cuz i was at a point of throwing the laggy one away and then i enabled interpolation and it started lagging again

#

even on the new movement script which is very tiny

cosmic rain
scarlet juniper
#

im the only one with access to the project

cosmic rain
#

Yeah, I mean, before that point.

scarlet juniper
#

no changes but the interpolation

cosmic rain
#

Interpolation shouldn't cause lag. In the worst case, it wouldn't do anything. That is with default physics settings

scarlet juniper
#

i hopped on, created a new simple movement script and turned on interpolation and it happened again

cosmic rain
#

Yeah, but you didn't answer my question. Did you touch the project - physics settings at any point in the project lifetime?

scarlet juniper
#

any point in the project lifetime, this project exists for almost a year now

#

but nothing of what i know about, i usually dont mess with physics settings

cosmic rain
#

Or maybe they went corrupt at some point. Can you share the settings? As well as the timestep settings(I think it's under project settings - time?)

scarlet juniper
#

never seen these settings so i'd assume these are regular values

dusky lake
cosmic rain
#

Hmm

scarlet juniper
#

i believe fen was going to try to recreate it cuz he also found it not making any sense

cosmic rain
#

Yeah, I'll give it a shot later as well. I've never encountered such a behaviour from interpolation and haven't seen anyone that did. Which make me think that it's something unique to your project or is a bug in your unity version.

scarlet juniper
#

im using 2022.3.8f1

#

im tomorrow going to start a new project and test it again to see it it misbehaves in that project aswell

hard viper
#

if I define a method/property with =>, will the compiler realize it should probably be inlined?

hard viper
#

!code

tawny elkBOT
lime patrol
hard viper
inner yarrow
#

Is there anyway to see the actually coding for how certain built-in methods work. For example, I'm trying to figure out how to set up custom oblique projection matrices, but I'm having trouble finding it, so I would like to see how the built-in one works to learn from it.

eager yacht
inner yarrow
tight drum
#

`
//Forces the player to slide down slopes that are too steep
private void SetSlopeVelocity()
{
if(Physics.Raycast(transform.position, Vector3.down, out RaycastHit hitInfo, 5))
{
float angle = Vector3.Angle(hitInfo.normal, Vector3.up);
Debug.Log("Slope Angle: " + angle);

        if (angle >= controller.slopeLimit)
        {

            slopeSlideVelocity = Vector3.ProjectOnPlane(new Vector3(0, ySpeed, 0), hitInfo.normal);
            return;
        }
    }

    slopeSlideVelocity = Vector3.zero;

}

//In update method
if(isSteepSliding)
{
movement = slopeSlideVelocity;

        movement.y = ySpeed;
        
        //movement.x += x * moveSpeed / 3;
        movement.z += -x * moveSpeed / 3;
    }

    controller.Move(movement * Time.deltaTime);
}

`

Why do I have to add the the z axis my "x" value, which is the value im getting from Input.GetAxis("Horizontal"); which too my understanding is the x axis, while vertical is the z axis as z is forward and backward and x is left and right? Also why does x have to be negative too? It doesnt make sense it should just be += x and += z???

cosmic rain
tight drum
#

idk im just really frusterated... I really want to get this functionality done tonight and its taking forever

#

Hoped someone would have a tip or somth

cosmic rain
#

Well, if you did write it, then we should ask you as to why would you write it like that.

tight drum
#

Well I didnt initially, I only changed it based on testing. It was initally just movement.x += x etc

cosmic rain
#

Your testings are probably incomplete. Try rotating your character and see if it still works.

tight drum
#

I already checked that lol, that was my first guess

#

If I rotate it, the rest of the movement functionality breaks

cosmic rain
#

So you're trying to say that it works correctly with the provided code?

cosmic rain
tight drum
#

No, I have the movement in one script atm, walking running, jumping, and in this case what im trying to work out, sliding down a slope thats too steep

#

However I dont want to take all control from the player, so I want them to be able to move slightly left or right when sliding

cosmic rain
#

I don't think it's a good idea to split movement related code into separate scripts.

tight drum
#

Well yeah, I have it in one

cosmic rain
#

Anyways, it's not clear what issue you have or what is the context of it.

tight drum
#

Alright, sorry Ill just keep at it, thanks for trying...

cosmic rain
#

Here's how you typically describe an issue:
I want X to happen, but with current code Y happens.
Relevant code:
code
Relevant scene screenshots:
screenshot
Maybe a video too if it's hard to explain with words.

tight drum
#

Well if thats the case, I would have worded it like this:

#

I want the player to be able to slightly adjust their velocity when sliding down a steep slope, the code will replace typical movement with a velocity that points down the slope.

However with current code, "A" and "D" keys makes player move forward and backward, whilst "W" and "S" keys make the player move left and right. While all other movement the player moves correctly given the keys.

Relavent Code:

`
//Forces the player to slide down slopes that are too steep
private void SetSlopeVelocity()
{
if(Physics.Raycast(transform.position, Vector3.down, out RaycastHit hitInfo, 5))
{
float angle = Vector3.Angle(hitInfo.normal, Vector3.up);

        if (angle >= controller.slopeLimit)
        {
            slopeSlideVelocity = Vector3.ProjectOnPlane(new Vector3(0, ySpeed, 0), hitInfo.normal);
            return;
        }
    }

    slopeSlideVelocity = Vector3.zero;

}

//Called in update function
if(isSteepSliding)
{
movement = slopeSlideVelocity;

        movement.y = ySpeed;
        
        movement.x += x * moveSpeed / 3;
        movement.z += z * moveSpeed / 3;
    }

    controller.Move(movement * Time.deltaTime);

//In InputController
public float GetX()
{
return Input.GetAxis("Horizontal");
}

public float GetZ()
{
    return Input.GetAxis("Vertical");
}

`

#

idk if that makes it any clearer

#

And all rotations are set to 0, and I have object tools set to global so x should be left and right with z forward and backwards relative to the player

cosmic rain
#

Maybe share the relevant script entirely following the guidelines
!code

tawny elkBOT
cosmic rain
#

As, at the moment It's not clear if it's all from one function/class or separate places.

tight drum
#

I would like to preface this is my first big unity project, ive only ever done small games and almost always 2d, so I have no idea if Im following best practice but I am really trying too

#

I am also open to just changing the implementation if I've done it poorly, just after a bunch of research this is the best I could do...

cosmic rain
#

That's a lot of calculations to figure out what's wrong just from looking at the code. I suggest debug logging all the intermediate values and/or do some visual debugging with debug rays to see that the calculations produce the values that you expect.

#

That way you'll be able to narrow the issue down to a certain line of code(or several) that are actually the cause.

devout harness
#

Also, the value of step debugging can't be overstated

south gorge
#

its not detecting collision

#

to change the varible.

somber nacelle
south gorge
#

i can't get it

#

hah

somber nacelle
#

have you confirmed with either a log or a breakpoint whether OnCollisionEnter is actually being called or not?

south gorge
#

it was working before

#

it just wont work with this information in the if statment

somber nacelle
#

okay but have you confirmed with either a log or a breakpoint whether OnCollisionEnter is actually being called or not?

south gorge
#

nooo, i have never used those before let me read it agian

somber nacelle
#

Debug.Log should have been like the first line of code you wrote in unity

south gorge
#

im self taught

somber nacelle
#

well you're clearly not learning the fundamentals. you should consider going through some basic courses to learn what you are actually doing

south gorge
#

u suck

somber nacelle
#

well i'm certainly not going to try helping you now

south gorge
#

u really werent helping

#

but my bad

#

ty anywy

somber nacelle
#

oh my bad, i'm guessing what you really wanted was for me to write the code for you so that you didn't have to do any work at all to figure out what the issue was. i'll come over and write Debug.Log("the code works"); for you so that you can see whether the method is actually being called

south gorge
#

you should not try and help people if you are not skilled at doing so

#

its art

#

i have put a lot of hours into learning this

#

and the last thing someone wants to hear is that they are not validated

#

when they are trying to learn

somber nacelle
#

stop making excuses about why you don't understand the bare minimum you need for unity and start putting effort into solving your issue

cosmic rain
#

In which case the best advice we can give you is to direct you towards learning the basics.

quartz folio
rocky helm
#

I'm pretty sure that there is a feature to make some serialized variables show up for example when another serialized bool variable is set to true, but I am unable to find it

somber nacelle
#

that is not a feature by default. you can use something like NaughtyAttributes or Odin Inspector which have attributes for that. or you can write some editor code yourself for it

rocky helm
somber tapir
hard viper
#

NaughtyAttributes is really good. strongly recommended

#

it just has a bunch of basic attributes to do things that Unity couldn’t be bothered to implement

vagrant blade
#

@steady moat We don't allow discussions on decompiling here, including sharing tools on how to do so.

regal epoch
#

I'm having trouble with my code, and I'm wondering:
If i have multiple scripts that add an onClick listener onto a button, will all the Listeners be triggered when I press this button, or only 1 of them?

somber nacelle
#

everything subscribed to the button's onClick event will be invoked when the method is invoked

regal epoch
#

okay that would explain my bugs. is there a way to avoid this? like instead of adding an onClick listener, replacing it?

#

im working with multiplayer, and the script is added to the playerpreffab. But since there are multiple players, the script is also called multiple times

somber nacelle
#

subscribe at runtime via code. then you can choose whether you should or should not subscribe based on whether the object is the local client or whatever your criteria is

regal epoch
#

well i managed to get it working by removing all the listeners on it first, and then adding 1. this way only the last player that connects will not get it removed. I know this is bad practise, but I have little time left to finish it for school. I will however change it later and only make it run once

#

Thanks for the help though!

thick socket
#
public async Task WaitAndDoSomethingAsync()
    {
        await Task.Delay(TimeSpan.FromSeconds(0.1)); // Wait for 0.1 seconds

        // Code to execute after waiting
        Console.WriteLine("Waited for 0.1 seconds, now doing something.");
    }

    public void DoSomething()
    {
        // Start waiting and doing something asynchronously
        WaitAndDoSomethingAsync().Wait();
    }
#

is doing something like this bad? atm the class isn't a monobehavior

leaden ice
#

Bad how? Isn't this a pretty standard case for delaying things?

#

If you went with a timer based solution you'd need another layer coordinating multiple calls to the function over time

#

E.g. a MB with Update to coordinate it

thick socket
#

it uses

#

threading.tasks

#

which for some reason thought was bad to do inside of unity

leaden ice
#

It's fine to do, but you need to understand the nuances of when your code is running on the main thread vs background thread.

#

In this case Unity will run it on the main thread

#

If you use Task.Run you'll get a background thread

#

Background threads are also fine as long as you understand the limitations like not touching Unity objects

thick socket
#

gotcha...I think

#

Im wanting to delay creating bullets so its in like a tiny "wave" instead of all at once

#
void CreateBulletSetStats(Vector3 position, Quaternion quaternion, float speed)
    {
        Bullet fireball;
        fireball = BulletPooling.instance.bulletPools[bullet].Get();
        fireball.transform.SetPositionAndRotation(position, quaternion);
        fireball.SetSpeed(speed);
        fireball.Fire(fighter.stats.attackDmg, fighter.tag, bulletType, fighter.enemyTarget);
    }
leaden ice
#

You'll want to also look into Unity's Awaitable (2023+) which gives much better async support than using System.Threading stuff

thick socket
#

it would call this function inside the task

leaden ice
#

Also if you want a consistent pattern you might need finer grained control over the timing which means something like waiting for FixedUpdate and maintaining your own timers

#

WaitForSeconds kind of stuff will "leak" milliseconds and make things look uneven.

thick socket
#

good to know thanks

#

this is for a "shotgun" style weapon so inaccuracy is great 😄

autumn field
#

If you end up wanting to use async and you’re using a pre-2023 version there’s the popular UniTask package on GitHub too

thick socket
#

I dont plan to use async hardly ever so hopefully it just works as I have rn

#

welp, something went horribly wrong

#
{.....
 WaitAndShoot(wait100ms).Wait();
 WaitAndShoot(wait200ms).Wait();
}
    TimeSpan wait100ms = TimeSpan.FromSeconds(0.1);
    TimeSpan wait200ms = TimeSpan.FromSeconds(0.2);
    public async Task WaitAndShoot(TimeSpan waitTime)
    {
        await Task.Delay(waitTime); // Wait for 0.1 seconds
        Quaternion rotation;
        int randomNumber;
        for (int i = 0; i < 3; i++)
        {
            randomNumber = UnityEngine.Random.Range(-10, 10);
            rotation = Quaternion.Euler(0, 0, randomNumber);
            CreateBulletSetStats(fighter.firePoint.position, fighter.firePoint.rotation * rotation, projSpeed);
        }
    }```
thick socket
#

Here is the main code it runs once the task "executes"

 void CreateBulletSetStats(Vector3 position, Quaternion quaternion, float speed)
    {
        Bullet fireball;
        fireball = BulletPooling.instance.bulletPools[bullet].Get();
        fireball.transform.SetPositionAndRotation(position, quaternion);
        fireball.SetSpeed(speed);
        fireball.Fire(fighter.stats.attackDmg, fighter.tag, bulletType, fighter.enemyTarget);
    }
autumn field
#

I would recommend against using the Task api without a Unity integration like the 2023 awaitables or UniTask. You’re asking for trouble unless you know what you’re doing. For instance, Task.Delay does not respect Unity timing or time scale

thick socket
#

but they wrote a 20 page paper on using it 😭

autumn field
#

UniTask exists so you don’t have to use coroutines

#

Coroutines are a byproduct of Unity not supporting modern c# features like async for a long time.

#

Now that they do, there are fewer scenarios where coroutines are optimal/necessary

#

You can wrap coroutines in a UniTask for compatibility/legacy purposes, but if you are the one writing asynchronous code it is not necessary to use coroutines at all cuz async supercedes their functionality and performance

autumn field
thick socket
#
  WaitAndShoot(wait100ms);
                WaitAndShoot(wait200ms);
                break;
        }
    }
    TimeSpan wait100ms = TimeSpan.FromSeconds(0.1);
    TimeSpan wait200ms = TimeSpan.FromSeconds(0.2);
    public async void WaitAndShoot(TimeSpan waitTime)
    {
        await UniTask.Delay(waitTime);
        Quaternion rotation;
        int randomNumber;
        for (int i = 0; i < 3; i++)
        {
            randomNumber = UnityEngine.Random.Range(-10, 10);
            rotation = Quaternion.Euler(0, 0, randomNumber);
            CreateBulletSetStats(fighter.firePoint.position, fighter.firePoint.rotation * rotation, projSpeed);
        }
    }
#

will see if it works lol

#

and it doesn't crash now!

#

thanks @autumn field never would have found that github by myself 🙂

#

last time I ran into this issue I had to redo like 3 classes to make them all monobehaviors lol

autumn field
#

No problem. If you have the patience I do recommend you read the docs since there’s still many ways to shoot yourself in the foot. But definitely less ways to mess up than using the standard Task api haha

eager fulcrum
#

Hey, I have problem with my collision

#
 public void OnTriggerStay2D(Collider2D collision)
 {
     Debug.Log("collision");
     if(collision.gameObject.CompareTag("Player"))
     {
         Debug.Log("2");
         _currentTime += Time.deltaTime;

         if(_stage == 0)
         {
             ChangeState();
         }

         if(_currentTime > TimeBetweenStages )
         {
             _currentTime = 0;
             ChangeState();
         }
     }
 }
#

(i tried bout OnTrigger and OnCollision)

#

i tried with and without trigger collider

#

and thats the player

eager fulcrum
autumn field
#

I think the tile might need a static/kinematic rigid body

eager fulcrum
#

when i added one my game starts to lag

#

for some reason

#

and i have like 50 tiles on the map

#

so having 50 rbs wont work here

autumn field
#

Did you set the rigid body to be static?

eager fulcrum
#

yep

autumn field
#

Looks like the tile doesn’t need a rigid body to receive trigger events if it’s static

#

Tho this is potentially just for 3D physics.

#

I don’t see another interaction matrix for 2d physics tho

eager fulcrum
#

ah thats so stupid

#

i guess i'll have to use something like OverlapBox or smth

#

but for some reason

#

on a different scene

#

i have this

#
private void OnTriggerStay2D(Collider2D other)
{
    if (!colliders.Contains(other.gameObject) && other.transform.CompareTag("Player")) 
    {
        MainMenuManager.Instance.PlayersInsideStartingArea++;
        colliders.Add(other.gameObject); 
    }
}
#

and it works just fine

#

with player only having rb

autumn field
#

Just a hunch

eager fulcrum
#

but i can have multiple players

#

standing on the platform

#

and i need to increment the timer when atleast one player stands on it

eager fulcrum
#

it doesnt make any sense

autumn field
# eager fulcrum but i can have multiple players

You can still handle that

OnTriggerEnter2D:
if (other is player)
player count++

OnTriggerEnter2D:
if (other is player)
player count—

// somewhere else, like Update or a coroutine
if player count > 1
timer += timeStep

eager fulcrum
#

ah yeah, my brain is not braining rn

#

ty

autumn field
eager fulcrum
#

nope and nope

autumn field
#

Just checking, cuz in the first screenshot, the tile does not have Is Trigger set to true like the Start Game Area

autumn field
#

I’m also assuming the player is configured the same when touching the start area vs a tile.

eager fulcrum
#

yup

autumn field
#

The only other thing I can think would be if the game objects are on a certain layer that doesn’t interact with one another. But if they’re colliding I don’t think that’s it

#

Might be worth asking again in #⚛️┃physics

Im on my phone so I can’t test anything and I’m probably just forgetting something obvious.

worldly pelican
#

I don't know if its notable or not but if I update my code the new behaviours apply to both versions so its essentially always broke in one scene or another.

somber tapir
#

I recommend subscribing/unsubscribing in OnDisable()/OnEnable()

worldly pelican
somber tapir
#

ye

worldly pelican
#

Interesting theory and forgive me if im wrong but I dont think thats the problem, that event is only called when I have dialog choices but the issues im encountering are not related to choices and just testing quickly by never subscribing to the event doesnt solve the issue

austere cape
#

hello guys I am loading 2 scenes together one for managers and the other one is the main scene so my manager scene override my main scene lighting how to solve this problem if anyone have any idea

somber tapir
austere cape
somber tapir
#

can't you just make em DDOL?

austere cape
unborn flame
#

why is my joystick not working? I am trying to make a joystick to move my charater around in a mobile game here is my code: https://hatebin.com/equgnftulk

somber tapir
unborn flame
#

inpector on the handle bar

unborn flame
somber tapir
#

set the inspector to Debug mode and check if isDragging is actually set to true

unborn flame
#

dragging is false

hybrid turtle
#

Hey guys I’m trying to make a script where when someone presses a button an animation on plays then at the end if they press the button again it resets and plays again

#

I know this is quite simple or should be

#

It’s screaming a coroutine

#

But how would I approach this

#

?

#
        {
           while(!_playableDirector.time.Equals(_playableDirector.duration))
           {
                yield return null; 
           }
           isEnd = true;    
        }
#

Ive tried this to wait until the end then set a flag and make an if in update that can use the flag

#

my full code is this

#
        {
           while(!_playableDirector.time.Equals(_playableDirector.duration))
           {
                yield return null; 
           }
           isEnd = true;    
        }

        void Update()
        {
            if (toggle.isOn)
            {
                _playableDirector.Play(); 
            }
            else if (isEnd && !toggle.isOn)
            {
                _playableDirector.Pause(); 
            }
            else 
            {
                _playableDirector.time = 0; 
                _playableDirector.Evaluate(); 
                _playableDirector.Play(); 
            }```
drifting trench
hybrid turtle
#

I mean I could

#

ik for sure it enters the condition though

#

like that works

#

it's just the functionality isn't workign

drifting trench
#

😵‍💫

hybrid turtle
#

yeah it sorta weird

#

but if anyone has an idea let me know gonna keep trying

heady iris
hybrid turtle
#

I've updated it to this

#
        {
            if (toggle.isOn)
                _playableDirector.Play(); 

            while (!_playableDirector.time.Equals(_playableDirector.duration))
            {
                while(!toggle.isOn)
                    yield return null; // wait for it 

                if (toggle.isOn)
                {
                    _playableDirector.time = 0;
                    _playableDirector.Evaluate(); 
                    _playableDirector.Play(); 
                }
                yield return null;  // wait every frame on the outer loop; 
            }
        }```
#

but doesnt seem to work still

#

but it only plays when the toggle is released

bronze tide
#

I am using this package for REST API requests: https://assetstore.unity.com/packages/tools/network/rest-client-for-unity-102501

        RestClient.Post<type>(url, data).Then(response =>
        {
        // ...
        }).Catch(Proyecto26.RequestException error =>
        {
            // ...
        });

Why doesn't this code work?
I get: Syntax error, ',' expected and 'RequestException' is a type, which is not valid in the given context

Get the Rest Client for Unity package from Proyecto 26 and speed up your game development process. Find this & other Network options on the Unity Asset Store.

worldly pelican
simple egret
bronze tide
#

but I left that out here

simple egret
#

Post the whole code unedited, so I don't false trigger on errors that are not there

bronze tide
bronze tide
simple egret
#

No type should be provided before the lambda parameter name

#

Just (error =>

bronze tide
simple egret
#

Nowhere

bronze tide
#

I am getting the wrong kind of error type

simple egret
#

It's inferred from the context

bronze tide
#

so I can't read data of it

#

I want to read error.Response but it's the wrong Type:
'Exception' does not contain a definition for 'Response' and no accessible extension method 'Response' accepting a first argument of type 'Exception' could be found (are you missing a using directive or an assembly reference?)

#

but Proyecto26.RequestException has a field called Response

simple egret
#

Seems like .Catch accepts a delegate that takes in an Exception only

#

If you are 150% sure the exception will be a Proyecto26.RequestException at runtime, then you can cast it in the lambda expression

#

error => ((Proyecto26.RequestException)error).Response

somber nacelle
#

could also type check it to be sure using the is operator

simple egret
#

But the cast will fail if the exception is not of that type

worldly pelican
# heady iris Where does the default dialog data live?

If you're referring to the actual dialog itself that started as a list of strings which is a serialized field in my NPC Controller, then I wanted to implement dialog options so I started using ink and added a serialized field TextAsset also in the NPC controller for the JSON

bronze tide
simple egret
#

No, not really

bronze tide
simple egret
#

Maybe Post<>() has a generic overload that takes both the response type and the exception type?

bronze tide
#

So you seperate the different types of errors

bronze tide
bronze tide
simple egret
#

Seeing the docs Post<T> it takes in a Action<RequestException, ResponseHelper, T> delegate type, investigating further

#

They're all void though, so I might be looking at the wrong thing since you couldn't possibly be using .Then on void

simple egret
#

You should be able to navigate to definition to see the exact declaration

bronze tide
#
        public static IPromise<T> Post<T>(string url, string bodyString)
        {
            return Post<T>(new RequestHelper { Uri = url, BodyString = bodyString });
        }
#
        public static IPromise<T> Post<T>(RequestHelper options)
        {
            var promise = new Promise<T>();
            Post<T>(options, promise.Promisify);
            return promise;
        }
#
        public static void Post<T>(RequestHelper options, Action<RequestException, ResponseHelper, T> callback)
        {
            options.Method = UnityWebRequest.kHttpVerbPOST;
            Request(options, callback);
        }
simple egret
#

Okay now to look at what IPromise<T>'s Catch method looks like

bronze tide
#

hmhm where should I look?

#

        /// <summary>
        /// Handle errors for the promise. 
        /// </summary>
        IPromise Catch(Action<Exception> onRejected);

        /// <summary>
        /// Handle errors for the promise. 
        /// </summary>
        IPromise<PromisedT> Catch(Func<Exception, PromisedT> onRejected);
#

there is this

simple egret
#

Okay so Exception it passes, cast at your own risk

bronze tide
simple egret
#

Exception is thrown

#

InvalidCastException to be precise

bronze tide
#

hmmh I have an idea:

bronze tide
# simple egret InvalidCastException to be precise

Can I just do something like:

        RestClient.Post<type>(url, data).Then(response =>
        {
        // ...
        }).Catch(error =>
        {
            try
            {
                RequestException ex = (RequestException)error;
                handleError(ex.Response);
            }
            catch
            {
                handleError(error.Message);
            }
        });
spring creek
bronze tide
bronze tide
simple egret
#

The GitHub repo of the project is also incomplete, didn't find any IPromise<T> interface nor the Post<T>() methods returning an implementation of it.
Most classes are partial though, so it may be exluded deliberately, although I don't see a reason for anyone to do that

spring creek
#

Still would take the compile error lol. I would rather it never run than fail 10% of the time randomly haha.

But no worries. I'll drop it

slim flint
#

Is there a way to have a 2D joint with constant pulling force and affected by gravity ?
I tried with the Spring Joint 2D but the force is proportional to the distance of the 2 Rigid Bodies and not constant.
I also tried with a Distance Joint 2D but I cannot control the pulling force and it seems to change the gravity a bit because the object I've attached the joint to is slowed down although it's going into the same direction as the pulling force of it.
It's hard to explain it aha
Maybe I should apply a force to the direction instead of using a joint ?

dusky lake
bronze tide
#

What is the easiest way to handle JSON data like this:

{
  "error": {
    "code": 400,
    "message": "EMAIL_EXISTS",
    "errors": [
      {
        "message": "EMAIL_EXISTS",
        "domain": "global",
        "reason": "invalid"
      }
    ]
  }
}

I did it like this:


[Serializable]
public class ErrorResponse2
{
    public List<ErrorResponse3> errors;
    public int code;
    public string message;
}
[Serializable]
public class ErrorResponse3
{
    public string domain;
    public string reason;
    public string message;
}
[Serializable]
public class ErrorResponse1
{
    public ErrorResponse2 error;
}

And then I used Newtonsoft JSON since the JsonUtility didn't work to deserialize it...
But that's a lot of work. Is there a better way?

#

Oh it seems there is the keyword dynamic for this?

#

And it seems you need to change the Api Compatibility Level to . NET 4.x and Scripting Backend IL2CPP for that
But is that possible with WebGL in Unity 2021 LTS? The option is grayed out...

bronze tide
polar marten
#

you made some other error. your modeling of the classes is fine, it will decode with JSONUtility correctly. you can test this easily by copying and pasting your string, and trying to deserialize it in a Start

#

do you have a screenshot of your webgl game?

polar marten
polar marten
sweet raft
#

Anyone know how to yield the result of a Coroutine? The documentation says it can be done, but doesn't give an example.

bronze tide
sweet raft
#

The issue is that putting yield return StartCoroutine(CoroutineB()) inside CoroutineA() doesn't actually wait for the started coroutine to finish. It just waits until there is a yield return somewhere inside CoroutineB(). So even if there's more code after yield return in CoroutineB(), CoroutineA() will already keep going.

bronze tide
bronze tide
somber nacelle
slim flint
dusky lake
#

Would be my first guess, actual math behind that might be a bit more complicated if you want it realistic

slim flint
#

Hm yeah but if you grab a wall, you will not get the same velocity because it does not move

dusky lake
#

Then apply half to each if you grapple a movable object, full on the player if its static

slim flint
#

The joints were perfect for this physics but I can't make one just pull at the same force everytime

somber nacelle
#
void Start()
{
    StartCoroutine(ACoroutine());
}
public IEnumerator ACoroutine()
{
    Debug.Log("Started Coroutine A");
    yield return StartCoroutine(BCoroutine());
    Debug.Log("Coroutine B should be done by now");
}
public IEnumerator BCoroutine()
{
    Debug.Log("Started Coroutine B");
    yield return new WaitForSeconds(1.5f);
    Debug.Log("Coroutine B halfway done!");
    yield return new WaitForSeconds(1.5f);
}
slim flint
sweet raft
# somber nacelle yielding a StartCoroutine call absolutely does wait for the coroutine to finish ...

No. I can say for a fact it does not, because I'm having this problem. Even the documentation says that it doesn't. Straight from the documentation : The StartCoroutine method returns upon the first yield return, however you can yield the result, which waits until the coroutine has finished execution. There is no guarantee coroutines end in the same order they started, even if they finish in the same frame.

So the first time you call yield return in your called Coroutine, the first Coroutine will stop yielding.

somber nacelle
#

i literally just showed you that it works

polar marten
# bronze tide I was able to use dynamic by using Mono (I was unable to change to il2cpp for so...
using System;
using System.Collections.Generic;
using UnityEngine;

namespace DefaultNamespace
{
  public class Test
  {
    [Serializable]
    public class ErrorResponse2
    {
      public List<ErrorResponse3> errors;
      public int code;
      public string message;
    }

    [Serializable]
    public class ErrorResponse3
    {
      public string domain;
      public string reason;
      public string message;
    }

    [Serializable]
    public class ErrorResponse1
    {
      public ErrorResponse2 error;
    }

    [RuntimeInitializeOnLoadMethod]
    public static void RunJson()
    {
      var str =
        "{\"error\":{\"code\":400,\"message\":\"EMAIL_EXISTS\",\"errors\":[{\"message\":\"EMAIL_EXISTS\",\"domain\":\"global\",\"reason\":\"invalid\"}]}}";
      Debug.Log(JsonUtility.ToJson(JsonUtility.FromJson<ErrorResponse1>(str), true));
    }
  }
}

this works correctly

#

you can see for yourself in the debug.log

polar marten
somber nacelle
#

and in case the previous code was not obvious enough for you:
https://paste.mod.gg/pytimzbodvqa/0

Coroutine A would have finished in under 1 second if it returned to execution after Coroutine B reached its first yield. but you can clearly see it took all 20 seconds for it to finish because that is how long Coroutine B took

dusky lake
#

1u mass on player, 2u on object = 1/3 force on player, 2/3 on object

slim flint
#

Wouldn't it be simpler with joints ? lol
Like Distance joint and Spring joint are almost what I want.
Problem with Distance joint is the pulling force not adjustable and the gravity weirdly applied,
and the problem with Spring joint is just that it's force is relative to the distance. Maybe there is math to make the SpringJoint frequency equal to pulling with the same force at any time ?

lean sail
slim flint
#

I want to do a grappling hook that when attached to a wall will pull the user with the same force at any time. So a constant force.
If an opposite force is being applied on the player that is stronger than the grappling hook then the grappling hook will extend.

lime patrol
lean sail
# slim flint I want to do a grappling hook that when attached to a wall will pull the user wi...

if its the same force everytime, in the direction from player to connection point, then add force sounds way easier. Otherwise you'll be fine tuning some joints and trying to adjust the damping/frequency based on some equation if one exists.
The grappling hook extending doesnt exactly matter since you'd be using the players current location and not the location of when they started hooking. The hook itself is just visual so that'll be like from your line renderer or however you choose to represent the hook rope

polar marten
#

do you understand what i mean?

polar marten
slim flint
lean sail
#

you could try to adjust the frequency based on distance to the object

slim flint
lean sail
#

the grappling hook is just a visual, the objects connected to the joint would move further away if you were applying enough force to counteract it

slim flint
#

This is with the spring joint.

It feels way more smooth and natural. For example you can see me doing circles around a block and I cannot do that with the Distance Joint because it does not "stretch". And the Spring joint can

#

But yeah the only thing is that the further I am the more force is applied.

#

The Distant Joint will always take the same time to travel to point A to B no matter the force applied in the opposite direction

#

With tests, a spring joint with 0 frequency makes it the stiffest possible and it makes the exact same result as the distance joint

#

So yeah the only thing I'm thinking is trying to change the frequency based on the distance so that it "cancels" the spring force

hybrid turtle
#
        {
            float elapsedTime = 0f; 
            while(elapsedTime < duration)
            {
                float t = elapsedTime/duration; 
                t = animationCurve.Evaluate(t);  
                flipModel.transform.position = Vector3.Lerp(flipModel.transform.position, flipModel.transform.position + new Vector3(0, offset, 0), t); 
                foldModel.transform.position = Vector3.Lerp(foldModel.transform.position, foldModel.transform.position + new Vector3(0, offset,0), t);  
                elapsedTime += Time.deltaTime; 
                yield return null; 
            }
        }
        ```
north marsh
#

Anyone know why Unity 2023.3.4 doesn't do reproducible builds when set to build the same way each time? GlobalGameManager is the file that changes

hybrid turtle
#

hey guys I wrote this script to make a simple translation animtion

#

do you know how I could create a bounce effect

#

and ease the animation

north marsh
#

Use an animation curve 🙂

hybrid turtle
#

I have :(((

#

it doesnt create the same bouncing effect I want

#

where it bobbles

#

I was looking and maybe Mathf.PingPong idk tho

leaden ice
#

you can also use a tween library

hybrid turtle
#

if im not mistaken

#

shoudlnt this have a bounce effect

leaden ice
#

you changed it

#

the Lerp is now incorrect

#

you need to save the start and end positions and use those in the lerp

#

not the current positions

#

that's why it's not working

hybrid turtle
#

yes this one is slightly different though im no longer trying to swap but rather just move two things up

leaden ice
#

it doesn't matter - you still need to save the start/end positions at the beginning and use those throughout the lerp

#

otherwise you will not get what you want

hybrid turtle
#

ok im probably being dumb here but my start was supposed to be foldModel.transform.position, foldModel.transform.position and then its ending position will be shifted by an ofset so the same thing + new Vector3(0, offset,0)

leaden ice
#

so they don't change during the animation

hybrid turtle
#

ok ok I see yeah im being dumb makes sense

#

ok it works now nicely

#

can you briefly explain why though its necessary

leaden ice
#

since you were putting in something OTHER than those expected parameters, you can only expect garbage to come out of the function

hybrid turtle
#

ok lol I was really having a brain fart thanks again @leaden ice

atomic sinew
latent latch
#

Did you log all conditions before the function

warm aspen
atomic sinew
atomic sinew
leaden ice
latent latch
#

You have 4 bools, so verify that they are correctly flagged to the required conditionn

atomic sinew
leaden ice
#

since it's not in the if statement

#

just print the values out

#

anything else right now is a waste of time

atomic sinew
# leaden ice isDashing isn't relevant

the screenshot shows the debug inspector is dashing is true and is cooling down is true.
is dashing is initialized at false and set to true only when Dash() is called, which should only be called when hasCooledDown is true, but it is not.

leaden ice
atomic sinew
leaden ice
#

all that matters is the state of the variables right at the moment before the if statement runs

#

you get that through Debug.Log or with the debugger

atomic sinew
#

ah forgot isdashing dammit

#

so it is false. and it is also marked as "true" in the debug inspector. why does the debug inspector lag?

#

but my player is still dashing.

leaden ice
leaden ice
#

also make sure Collapse is not turned on in the console window

atomic sinew
leaden ice
#

all of the other conditions are satisfied as per your screenshot above

atomic sinew
#

the isDashing stuff is at line 21

leaden ice
atomic sinew
#

in the update

leaden ice
#

if _isDashing is becoming false it's because StopDash(); is running

#

unless it's happening elsewhere in the script (not shared)

atomic sinew
# leaden ice what does that have to do with this code though

so for the background: dashing generally works in my game. however, when spamming the button and dashing against walls it can lead to a game-breaking bug, where the player is stuck in the wall and these are the relevant properties. so i see that i'm dashing because i'm stuck in the wall with my dashing animation, but isDashing is set to false. i'm not sure how this is possible

leaden ice
#

so you should be debugging that code

#

_initialXPosition = CenterOnTile(transform.position.x);

            float dashDirection = transform.localScale.x;
            float targetXPosition = _initialXPosition + dashDirection * _dashDistance;

            if (dashDirection * transform.position.x >= dashDirection * targetXPosition)```
#

all this stuff

#

also you're not checking if you are already dashing before allowing another dash to happen

atomic sinew
leaden ice
#

I feel like you have a bit too many variables that mean the same thing too which is leading to confusion. what's the difference between _isCoolingDown and _hasCoo0ledDOwn other than being opposites?

#

I also don't see _isCoolingDown = true; anywhere so I don't think the cooldown is being processed at all

#

oh I see, it's in StopDash()

#

so really don't you need to just add !_isDashing to the if statement about whether you can dash to prevent spamming?

leaden ice
atomic sinew
leaden ice
#

my guess is you're inverting the x scale which is going to bypass physics and invert your collider, putting it inside the wall, hence you get stuck.

atomic sinew
#

i still have the frame stopped now. the colliders look fine

#

it is also symmetrical

leaden ice
#

Try commenting that line out

#

that could be teleporting you into the wall

#

you generally never want to set the Transform position directly when using physics

atomic sinew
leaden ice
#

if you hit a wall first you won';t ever travel the required distance

atomic sinew
leaden ice
#

I don't really understand how that's supposed to work

#

but this seems very complex/convoluted

#

it's not surprising something is slipping through the cracks

#

why not do a boxcast or something before dashing to determine how far you can dash

atomic sinew
#

yes, unfortunately it is, but i couldnt find another way to get my player precisely into the middle of the tile

leaden ice
#

I'm not sure I understand what you mean by that or why it's desirable to be in the center of a tile

#

Is this a grid based game?

atomic sinew
atomic sinew
#

so if its a trigger i'll just dash past it, if it is solid StopDash() will be called

leaden ice
frozen sun
leaden ice
#

you may need to adjust the velocity down or use MovePosition on the final physics frame to reach the exact point

#

unless you're willing to have different overall dash velocities to satisfy that snappiness

atomic sinew
frozen sun
#

oh shit thanks bro :)

atomic sinew
leaden ice
atomic sinew
#

i would stil crash into a wall, the target tile will not be reached and the wall collider will be checked as !isTrigger and StopDash will be called just like it is now

leaden ice
#

the dash would always last a certain number of physics frames no matter what

atomic sinew
#

aah i see

#

so i need a combination of your idea and a boxcast to determine if something is between my player and the target tile?

#

or do you mean i would simply stop getting stuck after the dashtime?

#

i mean its about 0.16 seconds so i could live with tht

#

*that

leaden ice
#

come up with a shorter duration based on the distance the boxcast travelled before hitting something if it hits something

atomic sinew
warm aspen
leaden ice
# atomic sinew sorry i dont understand that sentence

basically:

  • boxcast to get the distance you will go unimpeded
  • take the next closest "center of tile position" closer to the player from that position
  • calculate the time it will take to go there
  • divide that time by Time.fixedDeltaTime and FloorToInt to get an int. Call this N
  • start dashing.
  • wait N physics frames
  • stop dashing
latent latch
#

why do you do a stop dash, why don't you just calculate the distance before dashing

#

assuming it's like some type of teleport

atomic sinew
#

ah yes because i feared i would go into walls, so yeah with a boxcast it should be fixed

#

theres more than only walls which i can bump into like bouncers and doors, so i thought !isTrigger was the best option

broken heron
#
    {
        // right-click
        if (Input.GetMouseButtonDown(1))
        {
            Debug.Log("Hotbar button right-clicked!");
            clickedButton = buttonClicked;
            ShowAbilityDropdown(clickedButton);
        }
        // left-click
        else if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("Hotbar button left-clicked!");
            GameAction action = GetActionFromButton(buttonClicked);

            if (action != null)
            {
                if (action.isOnCooldown)
                {
                    // If the action is on cooldown
                    // set the button's text to show remaining cooldown time.
                    float remainingCooldown = action.GetRemainingCooldownTime();
                    buttonClicked.GetComponentInChildren<TMP_Text>().text = remainingCooldown.ToString("0.0");
                }
                else
                {
                    // If the cooldown is over
                    // execute the action and start the cooldown.
                    action.Execute();
                    action.StartCooldown();
                    buttonClicked.GetComponentInChildren<TMP_Text>().text = "";
                    UpdateCooldownText(buttonClicked, action);
                }
            }
        }
    }

    // get the action associated with a button based on its sprite
    private GameAction GetActionFromButton(Button button)
    {
        Image buttonImage = button.GetComponent<Image>();
        if (buttonImage.sprite != defaultPlaceholderSprite)
        {
            foreach (var action in learnedActions)
            {
                if (action.LoadIcon() == buttonImage.sprite)
                {
                    return action;
                }
            }
        }
        return null;
    }
    private IEnumerator UpdateCooldownText(Button button, GameAction action)
    {

        while (action.isOnCooldown)
        {
            float remainingCooldown = action.GetRemainingCooldownTime();
            button.GetComponentInChildren<TMP_Text>().text = remainingCooldown.ToString("0.0");
            yield return new WaitForSeconds(0.1f); 
        }
        button.GetComponentInChildren<TMP_Text>().text = ""; 
    }
    public void StartCooldown()
    {
        lastExecutionTime = Time.time;
        isOnCooldown = true;
    }

I have a script that assigns the hotbar its sprite and on click executes the spell or abilty that is associated with that sprite. I wanted to add a visual countdown so there is a empty text on the sprite and I set up some code for it to work, however it only shows it after you click on the button after you initially called it and excuted. If I click the button any number of times during the cooldown timer it updates the text with that float value. What do I have wrong here?

leaden ice
#

if it's being started at all

#

Oh yeah looks like you're not even starting the coroutine

#

you're just doing UpdateCooldownText(buttonClicked, action); which won't do anything

#

to start a coroutine you need to use StartCoroutine

#

e.g.
StartCoroutine(UpdateCooldownText(buttonClicked, action));

broken heron
#

yep that was it, dammit ty. something so simple to.

analog igloo
#

im trying to build a game with a deferred camera but everything render black, if i switch urp setting to forward it work. What could be wrong?

#

in editor all work fine with both

sullen fern
#

I'm trying to get the current animation that is playing and get the length of the clip but for some reason it keeps getting the previous animation

#

ive used GetCurrentAnimatorStateInfo and GetCurrentAnimatorClipInfo

#

and both give the same result

leaden ice
kind halo
#

Is there a way to check by code if a material is read-only material (the one that is greyed out and can't be edited)?

sullen fern
long scarab
#

im messing around with events for the first time, but is there any reason to use c# events over unityevents?

kind halo
#

I actually didn't use event much myself(I use Action)

long scarab
#

okay, that seemed to be the only difference i could notice

#

how does Action work compared to Event?

kind halo
#

IDK that deep but Action is just easier to use for me

lean sail
long scarab
#

oh gotcha

lean sail
#

an event is something else entirely, an event only exposes the add and remove to these delegates. An event can only be invoked from within the same class

#

So if you just use a delegate/action without the event, anything can invoke your code

long scarab
#

i think ill have to use delegates then

#

im having enemies broadcast when they die so towers in my game can remove them from their targeting lists

lean sail
#

Thats fine with events, the enemy itself should be the only one notifying that its died

long scarab
#

i need the towers to be notified too, since each tower stores its own list of enemies within their range

#

just destroying the enemy leaves me with a null element

lean sail
long scarab
#

but didnt you say the event has to be called within the same class?

lean sail
#

hm can you show part of this code? sounds like your tower is handling things that the enemy should be

long scarab
#

Using this list to store all the enemies that are within tower range (current target is just the closest enemy in this list)

public List<GameObject> enemies = new List<GameObject>();
#

Using this trigger to see when the bullet hits and then damage the enemy via the takeDamage method

void OnTriggerEnter(Collider other)
    {
        Debug.Log("Bullet Reached Target");
        if(other.gameObject.tag == "Enemy")
        {
            HitTarget();
        }
    }
void HitTarget()
    {
        EnemyScript e = target.gameObject.GetComponent<EnemyScript>();
        e.takeDamage(damage, gameObject);
        Destroy(gameObject);
    }
#
public void takeDamage(float damage, GameObject damagerBullet)
    {
        currentHealth -= damage;
        if(currentHealth <= 0)
        {
            TowerBehavior t = damagerBullet.transform.parent.gameObject.GetComponent<TowerBehavior>();
            //t.enemies.Remove(gameObject);
            Destroy(gameObject);
        }
    }
#

^ this last snippet was giving me errors

#

so i wanted to just use an event to tell all towers the enemy died, remove that enemy from their lists, and then destroy the enemy GameObject

lean sail
#

yea I think that part is definitely questionable. your damage function can know what damaged it, but that'd be more for visuals, debugging, or a smart AI knowing who to go after.
You should just have the towers subscribe to the enemies death event when they're in range

#

And when they leave the range, unsubscribe

long scarab
#

still having a bit of trouble understanding the different uses of event, delegate, and action though

lean sail
# long scarab still having a bit of trouble understanding the different uses of event, delegat...

the simplest way would be like

public event Action OnDeath;

public void TakeDamage(float damage)
{
  // whatever damage calculation done here
        if(currentHealth <= 0)
        {
            OnDeath?.Invoke(); // null check to see if anything subscribed before invoking
            Destroy(gameObject);
        }
}

And when your enemies come in range of the tower you do

enemy.OnDeath += //Some method that removes the enemy from the list
long scarab
#

the code that goes in the tower is the part im lost at

#

maybe im just slow

lean sail
# long scarab still having a bit of trouble understanding the different uses of event, delegat...

an action is a delegate.

namespace System
{
public delegate void Action();
}

its just one that doesnt return anything, but it can take up to 16 parameters.
A delegate is kinda like a function pointer if you know c++. In a sense its a way to reference a function.
An event just takes this delegate or action, doesnt let any other class invoke it, and lets implements custom add/remove code (to the delegate chain)

lean sail
long scarab
#

OHHHHH

#

that little pointer bit made it make sense

#

so the delegate is just a placeholder for what is actually called when a listener hears the event

long scarab
#

so i would just add the event subscription in there when the enemy is added to the list

#

and then have a separate method in the tower that the delegate invokes

lean sail
desert blade
#

Heyo guys! I'm currently extending the Image component and just tried to put a public variable in the script but it doesn't show up in the inspector. Any ideas as to why? Much appreciated!

long scarab
#

ah, so you could call multiple methods with a delegate

#

gotcha

lean sail
long scarab
#

and one more thing, how would i pass a parameter through the event? I'd like to have the enemy pass its own GameObject so that the tower can just pull it from its list

#

or is there a way to just see which GameObject invoked the event

latent latch
desert blade
#
latent latch
hexed pecan
lean sail
#

im tired so im not sure if theres an alternative, you could use a lambda to not pass it in but then you cant remove the subscription. This might not actually be an issue for you but it could start to be one if an enemy keeps entering the trigger and keeps adding to the delegate chain

long scarab
long scarab
desert blade
floral rain
#

Hey there, I have a randomly generated map with a dynamic size, and I'm unsure how to make the borders seem infinite... Right now they look like this:

rocky helm
gray mural
#

I have a script with ExecuteInEditMode Attribute. Why does its OnValidate method execute in run mode?

gray mural
#

well, why is OnEnable called in play mode through..

knotty sun
gray mural
#
namespace UnityEngine
{
    //
    // Summary:
    //     Makes instances of a script always execute, both as part of Play Mode and when
    //     editing.
    [UsedByNativeCode]
    public sealed class ExecuteAlways : Attribute
    {
    }
}
knotty sun
gray mural
ebon wing
#

anyone know how i can detect what material/colouir a object is and then change it in code

#

also i shoujld probably note, it is a prefeab and a 3d model (from blender)

golden wave
#
Item newItemScript = newItem.GetComponent<Item>();```
Is there a difference between newItem and newItemScript here?
For example if I set the parent, can I use either one?
And if I pass the Item newItemScript to another function, can I use that to call functions on the GameObject?
#

I've noticed they are interchangable to some level, but would like to understand it better

oblique spoke
somber tapir
#

Item knows about it's gameObject but newItem doesn't know about it's script without using GetComponent

golden wave
#

so I guess newItemScript.gameObject just lets me access newItem?

somber tapir
#

you can also turn itemPrefab from a GameObject to a Item, then you can skip the GetComponent() call

knotty sun
#

btw SetParent is a method of Transform so it would be the same for both objects

golden wave
golden wave
somber tapir
#

doesn't matter though

oblique spoke
golden wave
#

ah yeah I know that, I just get the script cuz I need to do some things with it

#

ah you mean I can do Item newItem = Instantiate(itemPrefab); instead?

knotty sun
#

yes

golden wave
#

let me try

oblique spoke
#

Need to also change the prefab field type

golden wave
#

and that will still get the complete prefab?

#

can't test it now cuz I have a lot more code to fix 😛

#
newItem.name = itemSO.name;```
This would set the gameObject name not?
bronze tide
somber nacelle
#

it requires JIT compilation in order to work which is obviously not possible with IL2CPP

bronze tide
bronze tide
#

I know IL2CPP stands for intermediary language to c++

#

and dynamic isn't a thing in c++

#

but that doesn't say everything

floral rain
bronze tide
rocky helm
#

And I don't see the border ending anywhere

bronze tide
somber nacelle
somber nacelle
bronze tide
somber nacelle
#

why do you even want to use dynamic anyway?

bronze tide
somber nacelle
#

link it because i'm not going spelunking to find it myself

bronze tide
somber nacelle
#

ah you're using webgl which means you cannot use dynamic because it is IL2CPP

somber nacelle
#

at that point you may as well just deserialize into a Dictionary<string, object> if you must support deserializing into an unknown type. but it is certainly better to deserialize into a type you have created like you were trying to avoid

somber nacelle
#

no, it is only il2cpp

#

webgl has to be AOT compiled

bronze tide
somber nacelle
#

does it work in a build?

#

or have you only tried in the editor?

bronze tide
#

I haven't tested that, good point

somber nacelle
#

that literally supports what i just said

void stratus
#

is there a more effecient way to do all of the rest ones like the one above ?

somber nacelle
#

yeah, it would be to use collections instead of separately numbered variables. then you just use loops

void stratus
#

define collections

somber nacelle
#

array, list, other #💻┃code-beginner topics that are covered in the beginner courses pinned in that channel

somber tapir
void stratus
#

aight ty

void stratus
bronze tide
somber nacelle
#

you should really just do it the hard, but correct, way instead of trying to avoid c#'s convenient type safety

#

there are even websites that will generate c# code based on json schemas you pass

void stratus
somber tapir
bronze tide
void stratus
#

more like selecting one of the three

bronze tide
somber nacelle
bronze tide
somber nacelle
#

you create the relevant types that you will need for deserializing the data. you put those types in namespaces/folders/assemblies where they are necessary. i don't know what else you are expecting me to say?

bronze tide
#

So would you recommend to make a seperate file for the classes?

somber nacelle
#

the same way you name any other object. give it a name that makes it clear what its purpose is

bronze tide
bronze tide
somber nacelle
bronze tide
bronze tide
somber nacelle
#

just name them something that makes sense for you. i'm not going to do the thinking for you.

#

if their current terrible names are sufficient for you now, then just use those

bronze tide
somber nacelle
#

it doesn't matter what I think. it's your code. use names that make sense to you. make your own decisions

#

and you're not going to bait me into making your decisions or doing the thinking for you so stop trying

bronze tide
somber nacelle
#

why wasn't it fine the first time i said i wasn't going to?

bronze tide
bronze tide
#

I only changed
JsonUtility.FromJson<> to JsonConvert.DeserializeObject<> and I left the rest of my code the same

#

I can't reproduce the error so you're probably right

golden wave
#
Debug.Log(equipment.transform.Find("LeftHand"));
Transform equipmentSlot = equipment.transform.Find(item.ItemSO.ItemType.ToString());```
#

what am I doing wrong?

mellow sigil
#

What's on line 136?

golden wave
#

the 3rd line Transform equipmentSlot = equipment.transform.Find(item.ItemSO.ItemType.ToString());

fringe parcel
#

I can’t do nothing with the script, any help?

somber nacelle
proven path
#

Is there any way to use on pointer events on an object with a spriterenderer?

golden wave
#

Ew: if (equipmentSlot.childCount != 0)

somber nacelle
#

oh and obviously you'll need an EventSystem in the scene

proven path
#

I see, thank you!

golden wave
#

Ah nvm, I need to use the name of the itemType not try to conver the object to a string

main coral
#
    {
        try
        {
            await AuthenticationService.Instance.SignUpWithUsernamePasswordAsync(RegisterUsernameInput.text, RegisterPasswordInput.text);
        }
        catch (AuthenticationException ex)
        {
            // Compare error code to AuthenticationErrorCodes
            // Notify the player with the proper error message
            Debug.LogException(ex);
        }
        catch (RequestFailedException ex)
        {
            // Compare error code to CommonErrorCodes
            // Notify the player with the proper error message
            Debug.LogException(ex);
        }
    }```

How do I find out whether the registration was successful?
#
    {
        if (RegisterPasswordInput.text == RegisterPasswordRepeatInput.text)
        {
            // Rufe die asynchrone Methode auf und warte auf ihr Ergebnis
            Task signUpTask = SignUpWithUsernamePassword();

            // Warte, bis die Aufgabe abgeschlossen ist
            yield return new WaitUntil(() => signUpTask.IsCompleted);

            if (signUpTask.IsFaulted)
            {
                // Handle error
                Debug.LogError("Registration failed: " + signUpTask.Exception);
            }
            else
            {
                // Handle success
                Debug.Log("Registration successful.");
            }
        }
        else
        {
            Debug.LogError("Passwords do not match.");
        }
    }```
somber nacelle
leaden ice
main coral
#

private IEnumerator RegisterUser()
{
if (RegisterPasswordInput.text == RegisterPasswordRepeatInput.text)
{
// Rufe die asynchrone Methode auf und warte auf ihr Ergebnis
Task signUpTask = SignUpWithUsernamePassword();

        // Warte, bis die Aufgabe abgeschlossen ist
        yield return new WaitUntil(() => signUpTask.IsCompleted);

        if (signUpTask.IsFaulted)
        {
            // Handle error
            Debug.LogError("Registration failed: " + signUpTask.Exception);
        }
        else
        {
            // Handle success
            Debug.Log("Registration successful.");
        }
    }
    else
    {
        Debug.LogError("Passwords do not match.");
    }
}
cunning meteor
#

how do i make an onject always look at another object

somber nacelle
#

transform.LookAt

main coral
main coral
#

I want when register was success

somber nacelle
#

throw the exceptions if you want the task to end up faulted

cunning meteor
somber nacelle
#

no. did you even bother looking at the docs for it?

cunning meteor
#

no

somber nacelle
#

that should be the first thing you do when you learn about a method or property you don't know how to use

cunning meteor
ebon wing
#

how can i make it so after the reGuy gets to green guy it stops otherwise when the greenGuy gfoes to -5-5-5 the redguy does too

#

ig i can do

if(greenGuy.transform.position == new Vector3(-5, -5, -5)

#

nvm

#

i can make an empty and have it teleport to that

dense swan
#

hello, I'm trying to connect UnityEvent with argument, like this:

   private void OnEnable()
   {
       for (int i = 0; i < lampSwitches.Length; i++)
       {
           int id = i;
           InteractiveLight lampSwitch = lampSwitches[i];
           lampSwitch.onSwitchToggled.AddListener(delegate { OnLightSwitched(id); });
       }
   }

How do I disconnect it?

    private void OnDisable()
    {
        for (int i = 0; i < lampSwitches.Length; i++)
        {
            InteractiveLight lampSwitch = lampSwitches[i];
            lampSwitch.onSwitchToggled.RemoveListener(delegate { OnLightSwitched(i); });
        }
    }

this doesn't seem to work. The more I enable and disable it, the more UnityEvent is invoked.

fervent furnace
#

keep the reference

dense swan
#

how do I keep the reference? what is the type of the... delegate thing?
Will need to put it in a list or an array.

fervent furnace
#

where are the onSwitchToggles invoke? i think you can just call OnLightSwitched directly in there to prevent memory leak

leaden ice
thick socket
#

Im trying to have something bounce off a wall, and Im worried if I just grab its "_rb.velocity" it might do weird things on the bounce(since it already "hit" the wall), is there a way to grab the velocity from the prevous frame?

dense swan
thick socket
#

or should I just always keep track of prevous velocity in a variable

leaden ice
dense swan
thick socket
leaden ice
thick socket
frozen dock
#

Can somebody help - i need the local forward vector from a gameobject. Because even when i use rigidbody.transform.forward it moves kinda strange because the animator das not know.

This should for a strafing behaviour

        public override void MoveUnit(float movementSpeed)
        {
            if (unitLocomotionHandler.MovementInput == Vector2.zero || !unitLocomotionHandler.AcceptMovementInput)
            {
                return;
            }

            Vector3 localForward = rigidBody.transform.worldToLocalMatrix.MultiplyVector(rigidBody.transform.forward);
            Vector3 localRight = rigidBody.transform.worldToLocalMatrix.MultiplyVector(rigidBody.transform.right);

            Vector3 movement = unitLocomotionHandler.MovementInput.y * localForward + unitLocomotionHandler.MovementInput.x * localRight;

            Debug.Log(rigidBody, rigidBody);
            Debug.Log(localForward);
            
            movement.Normalize();

            Vector3 newPosition = rigidBody.position + movementSpeed * Time.deltaTime * movement;
            rigidBody.MovePosition(newPosition);
        }

        public override void RotateUnit(float rotationSpeed)
        {
            if (!unitLocomotionHandler.AcceptRotationInput)
            {
                return;
            }

            Quaternion targetRotation = Quaternion.LookRotation(npcSteeringMovement.GetTargetPosition() - rigidBody.position);
            targetRotation.x = 0f;
            targetRotation.z = 0f;

            rigidBody.rotation = Quaternion.Slerp(rigidBody.rotation, targetRotation, rotationSpeed * Time.deltaTime);
        }
dusky lake
#

just Vector3 localForward = rigidBody.transform.forward

leaden ice
leaden ice
leaden ice
#

That's not how any of that works

#

They're not euler angles

frozen dock
thick socket
#
Vector3 currentDirection = _rb.velocity;
            currentDirection = Vector3.Reflect(currentDirection, detectFrontNormal);
            _rb.velocity = currentDirection;
``` so this will "deflect" the correct direction for speed, how would I make sure to not (instantly) rotate to be facing the new way Im moving?
leaden ice
frozen dock
#

oh really? because i just wanted it to only rotate on the y axis

leaden ice
#

you should never be looking at the xyzw of a quaternion

#

pretend they don't exist

#

they don't mean what you think they mean

frozen dock
#

man those quarternions all the time - they black magic 😄

leaden ice
#
            Vector3 direction = Vector3.ProjectOnPlane(npcSteeringMovement.GetTargetPosition() - rigidBody.position, Vector3.up);
            Quaternion targetRotation = Quaternion.LookRotation(direction);```
thick socket
#
 float angle = Mathf.Atan2(rb.velocity.y, rb.velocity.x) * Mathf.Rad2Deg;
            transform.rotation = Quaternion.Euler(0, 0, angle);

should I be doing math like this or is there a nice function that already does this

leaden ice
dusky lake
leaden ice
#

I'd discourage that

#

euler angles are just sucky

#

Just learn how to use the Quaternion API

#

ignore the inner workings of them

#

and they work beautifully

dusky lake
#

Yeah i know, but sometimes its just easier / quicker to test

leaden ice
#

It only works if you treat all 3 euler angles as a set though. People try to do that and then isolate one of the axes

#

and that doesn't work

#

because euler angles are all interdependent on each other

#

it sometimes works, if you're lucky

dusky lake
#

Yeah i remember the head-scratcher when I first came into contact with that 😄

frozen dock
#

hmm so i tried it with

        public override void RotateUnit(float rotationSpeed)
        {
            if (!unitLocomotionHandler.AcceptRotationInput)
            {
                return;
            }

            Vector3 direction = Vector3.ProjectOnPlane(npcSteeringMovement.GetTargetPosition() - rigidBody.position, Vector3.up);
            Quaternion targetRotation = Quaternion.LookRotation(direction);

            rigidBody.rotation = Quaternion.Slerp(rigidBody.rotation, targetRotation, rotationSpeed * Time.deltaTime);
        }

but still the same behaviour. FYI the MovementInput Vector comes from

        private void SetMovementInputDirection()
        {
            if (navMeshPath == null || navMeshPath.corners.Length == 0)
            {
                return;
            }

            // if the npc is close to the target position, stop moving
            if (Vector3.Distance(npcMainManager.UnitMainManager.transform.position, GetTargetPosition()) < StoppingDistance)
            {
                npcMainManager.UnitMainManager.UnitLocomotionHandler.SetMovementInput(Vector2.zero);
                return;
            }

            Vector3 direction = (currentPathPoint - npcMainManager.UnitMainManager.transform.position).normalized;

            if (!isRunning || npcMainManager.UnitMainManager.UnitLocomotionHandler.MovementModeState == Unit.Animation.LocomotionState.Directional)
            {
                direction = direction.SetMagnitude(0.5f);
            }

            npcMainManager.UnitMainManager.UnitLocomotionHandler.SetMovementInput(new Vector2(direction.x, direction.z));
        }
#

but that should not matter

leaden ice
#

because I just did the rotation bit

frozen dock
#

but thats all for the strafing behaviour but when it is comming to its true directional movement it works fine

/// <summary>
/// Moves the rigidBody based on the movement input in true directional movement in local space.
/// </summary>
/// <param name="movementSpeed"></param>
public override void MoveUnit(float movementSpeed)
{
    if (unitLocomotionHandler.MovementInput == Vector2.zero || !unitLocomotionHandler.AcceptMovementInput)
    {
        return;
    }

    // Calculate the forward vector based on the Rigidbody's transform
    Vector3 forwardVector = rigidBody.transform.forward;
    forwardVector.y = 0f;
    forwardVector.Normalize();

    // Calculate the movement vector using the forward vector and movement speed
    Vector3 movement = movementSpeed * Time.deltaTime * forwardVector;

    // Move the Rigidbody's position using MovePosition
    rigidBody.MovePosition(rigidBody.position + movement);
}

public override void RotateUnit(float rotationSpeed)
{
    if (!unitLocomotionHandler.AcceptRotationInput || unitLocomotionHandler.MovementInput.magnitude == 0 || npcSteeringMovement == null)
    {
        return;
    }

    Vector3 targetDirection = npcSteeringMovement.currentPathPoint - rigidBody.position;

    if (targetDirection == Vector3.zero)
    {
        return;
    }

    Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
    targetRotation.x = 0f;
    targetRotation.z = 0f;

    if (rigidBody.rotation == targetRotation)
    {
        return;
    }

    // Rotate the Rigidbody towards the target rotation
    rigidBody.rotation = Quaternion.Slerp(rigidBody.rotation, Quaternion.Normalize(targetRotation), rotationSpeed * Time.deltaTime);
}
leaden ice
#
    Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
    targetRotation.x = 0f;
    targetRotation.z = 0f;```
#

you need to delete these last two lines

#

they are nonsense

#

Again if you want to rotate only on the y axis you do:

targetDirection = Vector3.ProjectOnPlane(targetDirection, Vector3.up);```
#

then you can use LookRotation

frozen dock
#

ahh good!

leaden ice
#

you also don't need to do Quaternion.Normalize(targetRotation)

#

(although you DID need to do that when you had the targetRotation.x = 0f; stuff)

frozen dock
#

ahhh alright

#

i really messed up here 😄

#

i think i know where the "bug" is

            Vector3 movement = unitLocomotionHandler.MovementInput.y * rigidBody.transform.forward + unitLocomotionHandler.MovementInput.x * rigidBody.transform.right;

Because the MovementInput is like the direction vector towards the target. So when i am standing on Position like Vector3(0,0,20) and the npc on Vector3(0,0,0) and looks to me with the rotation Rotation(0,0,0) then it is kinda fine. But when i am Vector3(0,0,-20) and the npc rotation is then Rotation(0,180,0) it gets messed up.

#

and the other problem would be then that the MovementInput Vector will also be used for the animator. So it walks "forward" the animator get for its vertical -1

        public override void MoveUnit(float movementSpeed)
        {
            if (unitLocomotionHandler.MovementInput == Vector2.zero || !unitLocomotionHandler.AcceptMovementInput)
            {
                return;
            }

            // Calculate the movement vector using the MovementInput and the transform's forward and right vectors
            Vector3 movement = unitLocomotionHandler.MovementInput.y * rigidBody.transform.forward + unitLocomotionHandler.MovementInput.x * rigidBody.transform.right;
            movement.Normalize();

            // Calculate the new position using MovePosition
            Vector3 newPosition = rigidBody.position + movementSpeed * Time.deltaTime * movement;
            rigidBody.MovePosition(newPosition);
        }
#

so looks like i need to seperate the MovementInput and the Values for the Animator. in the movement case. Because the goal was overall to have the same systems for ai and player so i dont need to write twice as much

#

and could easily controll a "npc" tooo

static matrix
#

specifying an Array[2] is going to be more efficient then creating a List that will always hold 2 items correct?

static matrix
#

great

frozen dock
#

it is mostly faster by accessing elements, but lists are faste by adding and removing

last island
#

So I can see that when I am testing in Play mode in the Editor and I have an Animator component that drives all animation of a UI...the animation restarts whenever I give focus back to the Play window making it neigh-on impossible to properly debug. What do I do instead? Do I switch all my Animator components out for Timeline or?

static matrix
#

does Array[2] create an array that can hold 2 items or one that can hold 3
because indexing

last island
#

Just like how Max Index is always capacity - 1

static matrix
#

woah why cant I type the letter k

#

literally 1984

#

can I do ok?

#

ok

#

cool

#

great

#

swell

#

ill shut up now

last island
#

How needlessly aggressive 😅

static matrix
#

actively 1984

#

anyways
ill get back to work

thick socket
#
public class ColliderDetectorBullet : MonoBehaviour
{
    private Bullet bullet;
    BoxCollider2D groundedBox;


    private void Awake()
    {
        bullet = GetComponent<Bullet>();
        groundedBox = GetComponent<BoxCollider2D>();
        groundedBox.enabled = false;
    }
    private void Update()
    {
        DetectFront();
    }
    [SerializeField] LayerMask mask;

    public void DetectFront()
    {

        Vector2 position = transform.position;
        position.x += groundedBox.offset.x;
        position.y += groundedBox.offset.y;
        RaycastHit2D[] hit = Physics2D.BoxCastAll(position, groundedBox.size, 0, Vector2.zero, 0, mask);

        if (hit.Length > 0)
        {
            bullet.detectFront = true;
            bullet.detectFrontNormal = hit[0].normal;
        }
        else
        {
            bullet.detectFront = false;
            bullet.detectFrontNormal = Vector3.zero;
        }
    }
}```
#

its not hitting my wall for some reason...and its only this wall also, the wall facing the other way works fine

#

is something in my code wrong so the cast is like "facing" the wrong way?

elfin tree
#

What am I doing wrong?

The value doesn't change much

#

(just trying to lerp)

main shuttle
last island
#

If only one wall is the problem

elfin tree
static matrix
#

i still access the array the same way as a list, right
(im not used to arrays I usually just use lists)

last island
#

Yes.

elfin tree
#

okay

last island
#

A list is just an array that gets resized

thick socket
#

meaning something with my code here is likely wrong