#archived-code-general
1 messages · Page 223 of 1
i’m just trying to straighten things out before I fill everythjng with sign errors trying to “fix” it
for ValueType I can just put Component or would it have to be a specific component
it’s whatever type you designate
It depends on what you want to do
what is this a dictionary of exactly?
Dictionary<string, int> myDict = new Dictionary<string, int>();
this is a dictionary that takes in strings, and outputs ints
what are you wanting to map to what?
Literally so I can prevent having to use too many repeated GetComponent<> throughout my project
whether it’s reference type or value type doesn’t make a difference
GetComponent is fine
This sounds like a premature optimization tbh, but in that case I guess you're wanting a Dictionary<Type, Component>
what's the scope of this thing though - is this on a particular script? This would have to be per GameObject basically
GetComponent is very good unless you are spamming it in like 10000 collision callbacks every frame
oh for sure, its definitely a premature optimisation but since this is my 3rd year uni project I'll be working on it for a long time
any feasible way of putting this into its own class so it can just be used as reference throughout the remainder of my scripts?
use GetComponent unless you identify a method that gets called a huge number of times a frame. then you can tie a dictionary to it
the only time I have used a dictionary to get around GetComponent calls is when making a physics system, to avoid caling GetComponent on every single cast/contact
as praetor says, this is premature optimization
I'm getting several serialization errors such as:
Trying to update the managed reference registry with invalid propertyPath(likely caused by a missing reference instance)'managedReferences[8989438259309051912].state.randomRepositionState', with value '-2'
I don't understand the error, I set the reference null on purpose because I didn't want to have an object there, why I get this?
I tried instantiating an object when it falls to a certain point, but the object doesn't instantiate.
Oh yeah, I forgot the code: https://pastecode.io/s/4j8vgx7z
what's the context in which you get the errors?
When I try to save a prefab
one semicolon per line please
Add a Debug.Log() inside your instantiate if statement and see if it gets called.
You will see that it doesn't since it's in start and start is only called once. So you need to put that code into Update(), but then it will Instantiate every frame so you need a bool to prevent that from happening.
When should I call the bool?
bool called 'hasAlreadySpawned', check if it is true before spawning and when you spawn you set it to true.
if (hasAlreadySpawned == false)
{
hasAlreadSpawned = true;
Instantiate();
}```
Okay I understand this might be a bit vague for now, but I have 2 scenes, MainMenu and Game, When I am in my Game scene and I open up my pause menu and return to the main menu via there, it obviously loads MainMenu scene and everything is fine, however the issue is when I press play again and it loads the Game scene again, my character controller does not move... the mouse look is fine, but no movement.
The weird thing is though, when I die in my game it returns to main menu and then when I press play from there and it reloads game scene, the player moves fine. So its only when going through my pause menu>mainmenu>play>loadgamescene and then no player movement.. any ideas?
Time.timeScale = 0 ?
ssounds like you forgot to reset something, e.g. timeScale
or some static bool that gets used for pausing when the menu is open, static variables persist through scene changes.
public ref AbilityBase GetAbilityFromSlot(AbilitySlot slot)
{
switch (slot)
{
case AbilitySlot.normal:
return ref normalSkill;
case AbilitySlot.mobility:
return ref mobilitySkill;
case AbilitySlot.specialOne:
return ref specialSkillOne;
case AbilitySlot.specialTwo:
return ref specialSkillTwo;
default:
return ref normalSkill;
}
}
does the ref keyword do anything different than just returning it? (AbilityBase is a class)
Returning a ref is pretty special.
Why not just make a dictionary at that point?
oh, dictionaries
i totally forgot about them
seems to be the thing i was looking for
This would indeed return one of those variables by reference, which would let someone else then assign into it
But I think it'd be easier if you just did a dict
yup. it seems to be the better design choice, thanks!
Switch is actually fine if you've this many skills
anyone able to assist? cinemachine input provider (using new input system) - the mouse sensitivity seems to be going extremely high at some points? I am not touching this at all via code.
2.9.7
I think that CinemachineInputProvider tries to factor into deltaTime
in CM 3.0, the input provider has a checkbox to disable that
yeah but i might add/remove/change them, dict feels better
I am not touching this at all via code.
weren't you just asking yesterday how to change the mouse sensitivity via code for this? did you not end up doing that? 🤔
same thing occurs even when the code touching sensitivity is commented out
and that script is only changing two values on void Awake(), not being dynamically updated or anything
any easy way to update to 3.0?
3.0 is a pretty big leap from 2.0. You wouldn't want to switch just for this
i never used cinemachine but it seems like an issue that would appear when using deltaTime / fixedDeltaTime incorrectly, maybe an option for that?
not touching delta time for this unfortunately
Also tried changing the Input System Update mode to "Process events in fixed update" but no change
damn
Are you using the POV aim component?
;') damn
It would be reasonably easy to fix this.
I usually make my "look" action absolute by adding a processor to my gamepad joystick input
which pre-multiplies the input by deltaTime
would that be the "normalize vector2" processor
In this case, you'd actually want to do the opposite.
You'd want to turn the mouse input from an absolute movement into a speed.
how should i handle multiple enemy ais so that they arent overlapping eachother
you would do this by dividing the mouse input by deltaTime, so that when it gets multiplied by deltaTime again, everything cancels out
this is pretty silly, but it'll make Cinemachine behave correctly
how would such a thing be added
is this a premade processor or
legend thank you
using UnityEditor;
using UnityEngine;
using UnityEngine.InputSystem;
#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public class DeltaTimeProcessor : InputProcessor<Vector2>
{
#if UNITY_EDITOR
static DeltaTimeProcessor()
{
Initialize();
}
#endif
[RuntimeInitializeOnLoadMethod]
static void Initialize()
{
InputSystem.RegisterProcessor<DeltaTimeProcessor>();
}
public override Vector2 Process(Vector2 value, InputControl control)
{
return value * Time.unscaledDeltaTime;
}
}
this is the code I'm using
you'd just change this...
return value / Time.deltaTime;
amusingly, Cinemachine 3.0 has a delta time processor that does this
value / Time.unscaledDeltaTime;
Oh so THAT'S what this is for
It's solving this exact problem lol
#if CINEMACHINE_UNITY_INPUTSYSTEM
using UnityEngine;
using UnityEngine.InputSystem;
/// <summary>
/// This processor scales the value by the inverse of deltaTime.
/// It's useful for time-normalizing framerate-sensitive inputs such as pointer delta.
/// </summary>
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
class DeltaTimeScaleProcessor : InputProcessor<Vector2>
{
/// <summary>Compensates for varialble deltaTime</summary>
/// <param name="value"></param>
/// <param name="control"></param>
/// <returns></returns>
public override Vector2 Process(Vector2 value, InputControl control) => value / Time.unscaledDeltaTime;
#if UNITY_EDITOR
static DeltaTimeScaleProcessor() => Initialize();
#endif
[RuntimeInitializeOnLoadMethod]
static void Initialize() => InputSystem.RegisterProcessor<DeltaTimeScaleProcessor>();
}
#endif
lol
Okay, so you could just paste this second script into your project. Just throw out the #if and #endif
It'll show up as an input processor
Add it to your pointer delta binding
You will need to adjust your input sensitivity downwards to compensate
perfect
My code is applied to joystick input to get an absolute delta
thank you so much
this is applied to mouse input to get a speed
what a pain in the ass this is lmao
To perfectly cancel out Cinemachine 2.0's problem, you'd need to use Time.deltaTime, instead of Time.unscaledDeltaTime
unscaledDeltaTime is correct -- we care about how much real time has passed
but it's using deltaTime
so, we must play by its rules!
I'm trying to use an Action with a Task, I did Action<Task<int>> but now how to invoke ?
I'll give it a go!
well, if it's a System.Action<Foo>, you must pass it a Foo
yea do I make a new Task ?
if you don't want to include this processor on the input action (for example if you only want it to apply to cinemachine) couldn't you just do this:
public class DeltaTimeInput : CinemachineInputProvider
{
public override float GetAxisValue(int axis) => base.GetAxisValue(axis) / Time.deltaTime;
}
and then just replace the CinemachineInputProvider component with this component
this would only solve the issue if it is actually being caused by a deltaTime multiplication though which may not actually be the case
I tried var number = 4;
var task = new Task<int>(number); but is not working
Argument 1: cannot convert from 'int' to 'System.Func<int>'
yeah you have to pass it a func that returns an int, not just an int
Issue still persists with this also
then it isn't being caused by a deltaTime multiplication
is there easier way to Invoke Action<Task<int>> ?
interesting
what are you actually trying to accomplish?
this is the code I have to set mouse sensitivity, but like I've said - only being called under void Awake() so it shouldn't be affecting anything
if (_cinemachinePov == null)
{
_cinemachinePov = firstPersonCam.GetCinemachineComponent<CinemachinePOV>();
var currentSens = _cinemachinePov.m_VerticalAxis.m_MaxSpeed;
var newSens = currentSens * sensitivity / 100;
_cinemachinePov.m_VerticalAxis.m_MaxSpeed = newSens;
_cinemachinePov.m_HorizontalAxis.m_MaxSpeed = newSens;
}
else
{
var currentSens = _cinemachinePov.m_VerticalAxis.m_MaxSpeed;
var newSens = currentSens * sensitivity / 100;
_cinemachinePov.m_VerticalAxis.m_MaxSpeed = newSens;
_cinemachinePov.m_HorizontalAxis.m_MaxSpeed = newSens;
}
I want a method to subscribe to Action<int> but it says return value not valid because the function is async Task
Action, by definition, is a delegate type for methods that return void
If you need to return anything else, then you want the Func<T, TRet> delegate
Func<int, Task> for example
I see, do I use Func instead of Action or I have to use delagate keyword?
this goofy ass cinemachine input provider stuff is murdering me
The former, you don't need to create a custom delegate type for this
my experience with it has been very poor. i think it's mostly these max speed / gain etc. parameters
yeah, I've got them set to max speed but I don't see any reason why I'm having the issues I am actually dealing with rn
just to be sure, this is okay ?
public event Func<int, Task> OnChangedValue;
Maybe? Accepts methods that take one argument of type int, and return Task
I may have actually found a stupid ass solution but it works
it was the shitty SmartUpdate within CinemachineBrain I think
worked as I needed thank you both @simple egret @somber nacelle
Sooo should you use Update() or not? I know people who dont use it at all.
You should use Update when appropriate.
I know I already made a similar thing, but nothing happens when a gameObject is on a certain point on the y axis.
Where you talking to me?
Any ideas why sometimes this is null ?
Did you do anything so it wouldnt be null?
sorry I changed the type to string, does that matter?
why don't you show your actual code
if there are no listeners when you invoke is gets a null ref. Check for null first:
yourEvent?.Invoke()
I did this
and where is the NRE happening
line 15
yea , I cleared by accident when I saved new script changes , only happens sometimes not always .
As soon as it happens again
okay, well most likely the issue is that something subscribed to the event is throwing the NRE not the event itself
the error can come from any listeners as well.
basically is trying to subscribe / unsubscribe to null event?
no . . . some method you have subscribed to the event is throwing a null reference exception when the event is invoked
the event itself is fine. you're already null checking that so it won't throw an NRE if the event is null
Thanks I will look into it, only have 1 subscribed and 1 that adds the history text from UI
I know I already made a similar thing, but nothing happens when a gameObject is on a certain point on the y axis.
you need to share your !code if you want help. and actually describe what you are expecting to happen
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
I will when I can access my computer.
sounds very cursed
Yeah, it gives that error every frame even when not in play mode, which I've never seen before
I'm trying to cast a ray from a parent object that should hit a child object, but it doesn't seem to register a hit.
public LayerMask mask;
Ray ray = camera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit, 100, mask))
{
Debug.Log("Hit object");
...
}
I've set a new mask on the relevant child object and that same mask is set on the script component of the parent in the inspector.
events are pretty rickety.
what do you expect to happen when you invoke a Func<Task, ?> event? if there are two async tasks, will they run concurrently, or will the first one added run to completion, then the second one; or, will the last one added run to completion; or if there's an exception in one, will it cause the other to fail?
are you authoring this code?
or is this from a chatbot or tutorial
The snippet I posted is what I'm attempting to do, but not the actual script in my project, if that's what you're asking.
I did write it, yeah
well there is nothing apparently wrong with this code, so maybe post the actual script
i assume you have a collider on your object that's under the mouse; that it's less than 100f away from the camera; that Vector3.Dot(ray.direction, normal of the face of the collider's geometry under the mouse) is positive aka you are outside of the collider you are trying to raycast onto; that you configured your mask correctly
There's not that much more to the code than what I posted, all it does is toggle a boolean which does some stuff in the update loop, nothing that should affect the ray hit.
How do I get the normal of the face of the target collider?
- You'd have to show the actual code, the scene setup, what the mask is set to, the layers of the objects, etc.
- You get the normal from the RaycastHit
when ContactHit2Ds are made with my kinematic RBs, the .relativeVelocity doesn't match the rigidbody.velocity
for kinematic RBs, I guess it would just use estimated velocity from MovePosition to calculate relative velocity I assume?
it doesn't sound like you understood what i wrote
Could be 😅
think deeply about what it means that you are inside or outside of the collider
when you do the raycast
are you inside of it?
is the camera inside the collider you expect to hit?
I'll take some screenshots of the scene
hmm. are you confused about the question?
No no, the camera is nowhere near the collider of the object I'm trying to hit
okay, is the object inside out?
hmm no
okay go ahead and send a screenshot of your scene. make sure your camera is visible. select the object you are trying to raycast. take a shot containing the whole inspector
you can try putting a sphere with an ordinary sphere collider in front of your camera, remove the mask line, and you'll observe everything works
Aaah you were right to call out the mask setup...
well...
I had set the mask during play mode
classic
But thanks anyway, I didn't know that being inside the collider could affect it registering a hit.
Or the object being inside out for that matter!
Is it possible to use ternary operator with a null check?
Yes, but in what context?
"if this GameObject reference is null"
Sorry, that isn't what I meant.
I meant show a code example
And do you mean null OPERATOR, or is/== null
Either way the answer would be yes, but you should never use a null operator on a gameobject
hmm I just wanted to do the shorthand using "?"
condition ? statement 1 : statement 2
No yeah, that is the ternary operator. And I said yes you can do that
But where would the null check be? (Condition, statement1, statement2?)
Show what you want to ACTUALLY write
note that the ternary operator has to return a value. you cannot just call methods that return void after the condition
myGameObjectRef == null ? statement 1 : statement 2
Then yeah, why not?
It's a boolean condition
Sorry. I swear I had tried that before and got errors
But as boxfriend said, you'd have to ASSSIGN it to something
Maybe that was the error?
That code alone is a syntax error
Okay, I wanted to assign references in the "statement" part.. for example
myGameObjectRef == null ? myInt = 1 : myInt = 2;
MyInt = condition ? Statment1 : statment2
It's messed up
The assignment always is on the left
ohhhhh
Thanks... For some reason I never grasped that important detail.
But yeah, I guess this won't work, becasue one of the conditions I essentially wanted to "do nothing"
I'm just tired of the ugly -
if(myRef == null) { myInt = 0; }
takes up so much space
What about
myInt = myGameObjectRef == null ? 1 : myInt;
Then it would just assign itself if the condition is false. Basically doing nothing
Or, I mean....
if(myRef == null) myInt = 0;
Oh nice, that could work
But I guess if you wanted to do something TO the gameobject you're checking the null status of, that would be impossible.. because if it's null, you can't do something to it
like "if gameObject != null, change it's scale. otherwise, do nothing"
In the ternary, the second statement would be if it is NOT null
Ah, or yeah you could just make it != in any of the examples
yeah whoops i switched it up
but i guess you can't tell the ternary to just "do nothing" in one of its statements?
if(myRef != null) /*change scale*/;
Not really, apart from how I said.
A ternary replaces a whole if else statement
Cool. Yeah at this point I'll acknowledge I'm splitting hairs
All good haha
For some reason I've never figured out ternary, and now I have, so thanks haha
This should be it
@knotty sun @leaden ice @somber tapir Thanks guys! That was it, the bool and resetting timescale to 1! Cheers!
Also, sorry I didn't respond, I was busy.
Why am I getting a routine is null error at the startcoroutine?
private int pointIndex = 0;
private Coroutine pathingCoroutine;
private void Start()
{
if (PathOnGameStart)
{
StartPathing();
}
}
public void StartPathing()
{
if (pathingCoroutine != null) StopCoroutine(pathingCoroutine);
pathingCoroutine = StartCoroutine(HandlePathing());
}
Look, I'll have to get back to you, I have a headache.
well... what is HandlePathing
also. always put curly braces around your if statements
should I use namespaces in unity?
Same as in normal c#
Just
namespace MyNamespace
{
}
always wondered if it was different in unity cuz unity doesnt make namespaces for u when u make a new script. thx
Yeah, it puts it in the global namespace by default
In the New Unity Input System, is there a way to have an always on ActionMap?
Or maybe secondary, additive? For actions that would be in all ActionMaps?
Or, do people just duplicate actions for some that are in multiple maps, usually?
You have full control over the action maps
Also #🖱️┃input-system exists
Maybe. It depends on context. People are available at different hours. Just repost your question.
private IEnumerator HandlePathing()
{
while (AIPathingPoints.Count > pointIndex)
{
PathPoint point = AIPathingPoints[pointIndex];
float elapsedTime = 0f;
transform.position = Vector3.MoveTowards(transform.position, point.PointTransform.position, LerpSpeed);
pointIndex++;
if (point.AutomaticallyStartNextPath)
{
yield return new WaitForSeconds(point.TimeUntilNextPath);
} else
{
yield break;
}
}
}
The transform isn't moving, it's moving like 2 spaces but not all the wqay to the position
anyone know why?
Because you're only doing one Move towards call before moving on to the next point
But it isn'
I would expect an inner loop here where you move frame by frame towards the point until reaching it
But it doesn't go to the next point all the way
Yes I explained why here
How would I fix it?
Explained here
Is it not looping, immediately finishing after one iteration or?
It stops if it isn't set to start the next path
Well, yield break stops the coroutine doesn't it?
It does
What's the problem?
yeah, there's a few workarounds i can think about but heh, not much cleaner than duplicating... and thanks didn't know
also found this in the meantime https://forum.unity.com/threads/layered-action-maps.788465/
which someone from unity called high priority 4 years ago
I am making an AI controller, the way it works is you give it multiple transforms, it will loop through the transforms, move to it, and then check if you want to automatically move onto the next one or trigger it manually
Make it not required being set to start of next path or don't break if not set to start of next path
Wild conclusion haha. Just post your question. Maybe someone can help. I dunno what to do with "I can talk now"
He'll be able to talk again in an hour or so 
this is what I'm trying to do
I want to lerp or move smoothly to the point
I'll be putting my daughter to sleep then, so hopefully they can be patient next time 😂
but if theres a next point, it stops if the point says so it can be triggered manually
I've heard what you said but your current code stops if the if-statement isn't true.
so how do I keep the move to running so that the movement completes
then the if statement fires
I'm trying to instantiate a new puyo when it reaches the bottom, but that's not happening. Code: https://pastecode.io/s/k5qe9n4i
Exact comparison of floating point numbers is very unreliable
So you have two checks for if the y position is -5.5. That is interesting.
As dlich said, floating point impricision is an issue here. It's probably never exactly -5.5.
You should do <= rather than ==
Don't increment point index until you've reached the destination.
How do I know when I'm at the destination
Did you write this code?
I did
Remove the latter stuff (if-statement) if you're not ready to implement it. Seems like start and destination was implemented with no in-between (actual moving) done.
I am implementing it
I can
I can't remove that part it's part of my planned logic
It's an array of points
while ...
get ready
//you need to implement an actual move cycle
immediately finish```
it loops through the points, once it gets to a point that says "Hey, don't go to the point after me"
No idea what you mean by workarounds, you can just directly enable or disable whichever maps you want
You sure? The method I use is called SwitchCurrentActionMap, and I don't know which one would additively load them?
Don't use that. That's just a convenience tool for PlayerInput
Instead, access the maps directly through myPlayerInput.actions.FindActionMap for example
The concept of a "current" action map is specific to PlayerInput and it disables all other action maps
I generally don't use PlayerInput anyway
But it's useful for local multiplayer if you're doing that
I am doing that but maybe that's a whole other topic? Curious though!
So something like this would load additively I assume?
ahh.. got it!
Disable() to disable it
and if i use SwitchCurrentActionMap it will disable every thing except that one i assume?
Yes
and how was that relevant to local coop?
i did a 'bad' implementation for now for the 2nd player
but curious what kind of techniques you'd use
so I can start thinking about it, for when I do it properly
(or relevant documentation)
PlayerInput and PlayerInputManager work together to automatically handle user device mapping in local multiplayer
Would manually using .Enable() and .Disable() break this functionnality?
No
Oh okay, thanks!
I just realized this is still using PlayerInput, so should be fine (after re-reading what you said earlier)
#🏃┃animation question
So uh, I put the variable in the right script, but now there's a new problem. It spawns multiple puyo when it's supposed to only spawn one. https://pastecode.io/s/keke06zy
Ok, I think my timing for collision callbacks is off, based on the code I'm trying to migrate
Looks like you don't check which collider is entering the trigger. Just ANY collision is setting it off
Oh, and you just have it spawn two for every collision
It would be easier to read if you formatted your code better
void OnTriggerEnter(Collider other)
{
{
int puyoIndex = Random.Range(0, puyo.Length);
Instantiate(puyo[puyoIndex], new Vector3(-12.5f, 5.5f, 0), puyo[puyoIndex].transform.rotation);
}
{
int puyo2Index = Random.Range(0, puyo2.Length);
Instantiate(puyo2[puyo2Index], new Vector3(-12.5f, 4.5f, 0), puyo2[puyo2Index].transform.rotation);
}
}
Those inner scopes (the curly braces) don't make much sense
It looks like you have (for dynamic RBs):
- Fixed update starts at pos1, vel1
- Physics update calculates pos2, vel2. Sets rb.position = pos2, rb.velocity = vel2
- Physics generates contacts and callbacks at pos2
but that doesn't seem to be the case for kinematic RBs?
I'm so confused
How do I fix it?
With if statements. Check for a script on the collider, or check for a tag, or check the physics layer
I think I figured out how to make the manual simulation maybe work right.
At end of simulation, I know currentPos and nextPos. I rigidBody.position = nextPos; rb.velocity = Vector2.zero; Physics2D.Simulate(); before collision callbacks set rb.velocity = nextVelocity;
this way it generates contacts at the new position.
at this stage, you have endured an endless parade of tedious obstacles that are more or less the same as what you would have had in ECS
you should switch to ECS, and try to implement your preferred physics there
I'm mostly crossing the finish line
so no, I do not want to start over again.
again
I'm currently in the implementation stage of getting collision callbacks to match, so I don't have to refactor a huge number of classes to use my new physics API
at the end of the day, what I have right now only really relies on Unity to make shapes, use Box2D to calculate Cast/Overlap/Distance, and relies on unity to generate contacts/collision callbacks
hey guys. Im writting a line of code to enable a certain amount of gameobjects from a list of gameobjects. So say the list has 10 gameobjects, but I only want to load 2 of them. Could anyone possible help me in figuring out a system for this function?
how do you determine what objects or how many of them you need to enable?
just use a for loop?
for (int i = 0; i < numberToEnable && i < list.Count; i++) {
list[i].SetActive(true);
}```
for example^
alternatively
for (int i = 0; i < list.Count; i++) {
list[i].SetActive(i < numberToEnable);
}
if you want to make sure that you disable ones that appear later in the list
yeah - instructions are pretty unclear here
ah. you guys are awesome. I don't know how that slipped my mind. thanks
private void UseCharacter(int characterIndex)
{
if (_spawnedCharacter != null) Destroy(_spawnedCharacter);
_spawnedCharacter = Instantiate(characterPrefabs[characterIndex], transform);
var spawnedAnimator = _spawnedCharacter.GetComponent<Animator>();
var spawnedAvatar = spawnedAnimator.avatar;
// Set the avatar of the main character's animator
_animator.avatar = spawnedAvatar;
// Destroy the spawned character's animator after setting the avatar
Destroy(spawnedAnimator);
GameObject rootTransform = Utility.GetChildTransformByName(gameObject, "Root").gameObject;
rootTransform.gameObject.SetActive(true);
_rightHand = Utility.GetChildTransformByName(gameObject, "Hand_R").transform;
Instantiate(weaponPrefab, _rightHand);
_animator.enabled = false;
_animator.enabled = true;
_animator.Rebind();
_animator.WriteDefaultValues();
OnCharacterSkinChange?.Invoke();
}
Changing avatar at runtime is not working character stays in T pose. If i manually enable and disable animator in runtime its working. Any help please?
Hi there!
So there is 2 problems I currently got and I think one of them can be fixed in code so that why i'm explaining it here:
Here's my problem, I am currently play testing the game I am working on (It's a maze game, something simple to try starting off with game development)
But when I go to test the game, it's as if the player is constantly getting stuck on the walls, it's like the walls are made of honey and the player has a hard time continuing moving around.
Not sure exactly what could be causing this issue, I did use a random maze generator as I really don't have the time nor patience to make a maze, wall by wall (Tried that in the past and it was not fun)
I will provide the current player movement code if needed but it's pretty much the exact same as before so nothing really got changed...
Thanks in advance! 🙂
Other problem (2/2) Is more of a visual issue I don't think evolves code so I will talk about that later in a diff channel to not take it off topic. ya know?
Share a video demonstrating the issue first as it's not entirely clear what you mean.
Sure, ok give me like 5 - 10 minutes?
Here it is, I have also shown the other issue I was talking about in #💻┃unity-talk so...
It doesn't make it any clearer
You can upload it somewhere, but I'm currently at work, and there's no guarantee I'll have time for that later either.
Share the code. Maybe we can guess something from it.
ok one second
here ya go
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.Windows;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed = 5f;
public float rotationSpeed = 2f;
private Rigidbody rb;
private Camera mainCamera;
private float cameraRotationX = 0f;
void Start()
{
rb = GetComponent<Rigidbody>();
//Freeze Rotation:
rb.freezeRotation = true;
mainCamera = Camera.main;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
// Player movement
float horizontalInput = UnityEngine.Input.GetAxis("Horizontal");
float verticalInput = UnityEngine.Input.GetAxis("Vertical");
Vector3 movement = new Vector3(horizontalInput, 0f, verticalInput).normalized;
Vector3 velocity = (transform.forward * verticalInput + transform.right * horizontalInput).normalized * moveSpeed;
rb.velocity = new Vector3(velocity.x, rb.velocity.y, velocity.z);
// Player rotation based on mouse input
float mouseX = UnityEngine.Input.GetAxis("Mouse X") * rotationSpeed;
transform.Rotate(Vector3.up * mouseX);
// Camera rotation based on mouse input
float mouseY = UnityEngine.Input.GetAxis("Mouse Y") * rotationSpeed;
// Invert the mouseY input to make it feel more intuitive
mouseY *= -1;
// Rotate the camera up and down
cameraRotationX += mouseY;
cameraRotationX = Mathf.Clamp(cameraRotationX, -90f, 90f);
mainCamera.transform.localRotation = Quaternion.Euler(cameraRotationX, 0f, 0f);
}
}
!code
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
But I don't see anything that would make you "stick to the walls".
well idk how else to explain it so 🤷♂️
maybe give your rigidbody and ground a physic material with 0 friction?
Hi everyone. Im new to the discord, but I've been using unity for years.
is there any way to easily block specific raycasts?
Or am I going to have to write my own script blocking/allowing specific ones?
I have a chatbox that I want to be able to click through, but I want to still be able to scroll within it.
Which means I have to have raycasts enabled.
Your raycast can have specific layers it can cast on, doesn't that fix your issue?
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
How would that work though? I'm getting stuck on the walls, not the ground.
you are applying force to walls when you are walking so friction applies
not sure about this though
a similar thing happened to me once
Kinda.
It just means I have to write a script for it lol.
Assets\Scripts\Tool Data\WebSocketHandler.cs(3,7): error CS0246: The type or namespace name 'WebSocketSharp' could not be found (are you missing a using directive or an assembly reference?)
I don't know how to fix it, since the "using Websocketsharp" is working perfectly fine in the code itself with no errors. This only comes when i try to build.
using UnityEngine;
using WebSocketSharp;
using WebSocketSharp.Net;
using WebSocketSharp.Server;
using Newtonsoft.Json;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System;
using TMPro;
public class WebSocketHandler : MonoBehaviour
{
public TMP_Text uiText; // Reference to your UI Text component in Unity
private WebSocket ws;
private void Start()
{
ConnectToWebSocket();
StartCoroutine(UpdateDataRoutine(2f)); // Update data every 2 seconds
}
private void ConnectToWebSocket()
{
ws = new WebSocket("wss://");
ws.OnMessage += (sender, e) =>
{
Debug.Log("Received: " + e.Data);
// Use Newtonsoft.Json to deserialize the JSON data received
YourData yourData = JsonConvert.DeserializeObject<YourData>(e.Data);
// Update the UI text with received data
UpdateUIText(yourData.textProperty);
};
// If Node-RED requires authentication
ws.SetCredentials("sfl", "password", true);
ws.Connect();
}
... more code here
I dont understand this because i added the package in the NuGet console in VS succesfully...
there is your problem, Unity does not recognise packages added via NuGet in VS
How do i fix that? Since my NuGet in Unity is broken...
- I need the right version for 2020.3.33f1
I presume Websocketsharp is provided as dll, so locate that and copy it to a Plugins folder in your project.
Google has lots of advice on this
Ah it worked, thank you.
What should I use for sending events between devices?
Checking a database is inefficient, so it networking
how would you expect any 2 devices to communicate with each other without using some kind of network protocol?
I meant the built-in multiplayer networking
so roll your own
Whot?
write your own networking code.
if you need bi-directional comms then you need TCP tunnelling
if it's uni-directional then a simple TCP Client/Server will do
Hey guys do you know how can i add a value to a quaternion but only on y axis (like euler angles) but without using euler angles?
Because i am using a Quaternion.RotateTowards function and i want object to look at another object plus a little more to the left for example
And normally i would do that using eulerAngles.y + value, but since i am using Quaternion i have no idea how to do it
Quaternion.Euler returns quaternion
How should i implement that?
Vector3 direction = target.transform.position - rotator.position;
direction.y = 0;
Quaternion desiredRotation = Quaternion.LookRotation(direction);
rotator.rotation = Quaternion.RotateTowards(rotator.rotation, desiredRotation, Time.deltaTime * 350);
My code
hmm cant you just add offset to target?
On which axis tho, it is a 3d space
target.transform.position + -target.transform.right * offset;
maybe something like
i'll try that
Aright seems good thanks
Between asking for NavmeshAgent.remainingDistance and calling Vector3.Distance(vector3a,vector3b) , which one is cheaper?
idk about cheaper but they will give different results obv
yes. I'm currently in a situation where both method serve my purpose. I just wanna trigger something if the navmeshAgent arrived. (or perhaps there is better way to do that?)
i wouldnt worry about premature optimization unless you were having a real problem with performance
I typically use V3.Distance to have extra redundancy, and not rely on navmesh or paths just in case
both are valid though afaik
imagine a spot where its a floor above you , you're technically closer than you would be if you calculated the whole path remaining
so yeah it can cause issues like that I suppose
Hey! I need some help with a thing. I have an interaction system for npcs that will display text when talking. I already have all that. The way I do it tho is I have a queue of strings that it will display after I interact more. But I want after it has displayed one of the strings in this case the 4th in the queue for it to call a different method. Kind of like a reward so the npc gives the player gold. How should I go by doing that? I can show any kind of code needed.
Thanks
where is your script that attaches to your text box?
can you send it here
Wdym? Does this look like the correct one?
yeah so send the code from in that
Its a bit long so ill send this ```cs
public void DisplayNextParagraph(DialogueText dialogueText, GameObject interactedNPC)
{
currentInteractedNPC = interactedNPC;
//if there isnt anything in the queue
if (paragraphs.Count == 0)
{
if(!conversationEnded)
{
//Start convo
StartConversation(dialogueText);
}
else if (conversationEnded && !isTyping)
{
//End convo
EndConversaton();
return;
}
}
//if there is something in the queue
if (!isTyping)
{
p = paragraphs.Dequeue();
typeDialogueCoroutine = StartCoroutine(TypeDialogueText(p));
}
else // Paragraph IS being typed out
{
FinishParagrapghEarly();
}
//NPCDialogueText.text = p;
if (paragraphs.Count == 0 )
{
conversationEnded = true;
}
}
private void StartConversation(DialogueText dialogueText)
{
if (!gameObject.activeSelf)
{
gameObject.SetActive(true);
}
//This is where it decides what to look at I just need a way to reference the npc it interacted with
npcCam.gameObject.SetActive(true);
npcCam.LookAt = currentInteractedNPC.transform;
npcCam.Follow = currentInteractedNPC.transform;
//update name
NPCNameText.text = dialogueText.speakerName;
//add dialogue
for (int i = 0; i < dialogueText.paragraphs.Length; i++)
{
paragraphs.Enqueue(dialogueText.paragraphs[i]);
}
}
private void EndConversaton()
{
npcCam.gameObject.SetActive(false);
//Clear queue
paragraphs.Clear();
//Return bool to false
conversationEnded = false;
//Deactivate text window
if (gameObject.activeSelf)
{
gameObject.SetActive(false);
}
}```c#
I did doesnt look like it changed anything. Or I just didnt notice
You might also want to look at Yarn Spinner, it's a free package that handles dialogues and allows you to call methods from within the dialogue texts.
yeah that probably is your best bet the only other way i can think is storing whatever string your up to then using if statements to check when your on array index 4
or 3 since index's start at 0
Im gonna check out Yarn Spinner thank you!
good luck
just so you know that its good some games that use yarn spinner are: Night in the Woods, A Short Hike, Lost in Random, Dredge, Frog Detective, Button City, Escape Academy, Baladins, and Unbeatable
Only heard of dredge love the game so yeah this seems like a good choice. Thanks a lot
Hello! I am writing a (should be) simple function where my goal is to get the parent object of the selected gameobject, which sounds and should be simple, but it somehow does not give me the parent object to me. I must be missing something but i can't see what it is.
public void OnSelectEntered(SelectEnterEventArgs args)
{
selectedChildObject = args.interactableObject.transform.gameObject;
selectedParentObject = selectedChildObject.transform.parent.gameObject;
}
which line is 18?
Oh woops. line 18 is the 'selectparentObject' one
then either selectedChildObject is null or it doesn't have a parent therefore selectedChildObject.transform.parent is null
use Debug.Log or the debugger to find out which
Oh it doesn't show it correctly that i uploaded 3 images, but if you use the arrow keys at the image you can see that selectedChildObject does have a parent object and that it is not null.
I did just figure out that when i simply drag in the gameobject in selectedChildObject that it does give me the parent, so i think it has to do something with the SelectEnterEventArgs args.
none of those other screenshots really matter
if the line you gave was the error
then there are only those two possibilities
yeah that's true. let me double double check it
So you are making some incorrect assumption about which object this is perhaps
Figured it out. The parent returned null and it was indeed me making assumptions on where it went wrong. Thank you!
indeed . . .
So I have a script to pick up an object, I'm working in 2D btw, how would I stop the player from being able to put the object inside of walls? I have the collider disabled right now so it doesn't collide with the player, but even with it on it still happens. Here is my code:
never move an object with transform.position if you want it to respect physics
What would be your solution?
you'd have to move the object either via forces/velocity on the Rigidbody, or attach a joint to it.
for a held object, an invisible kinematic rigidbody which you move around and the held object attached to that via a joint of some kind is decent
So I have this piece of code, which is meant to go over list of Rects and remove "part" of rect if it overlaps with newRect.
But something is wrong with it and instead out of area 50-50 it creates, two areas of 5,0,45,50 and 0,5,50,45 when i try to set 0,0,5,5 rect.
What I need instead: 0,5,5,45 and 5,0,45,50 rects.
https://pastebin.com/1Yt877h3
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
basically, if I try to Set green rect on picture into red rect. I want it to create 2 blue rects instead.
So I got it working using forces, but now it's super jittery:
rb.MovePosition(holdPosition);is not using forces. MovePosition also doesn't respect collisions.rb.MovePosition(holdPosition);should only be used in FixedUpdate.
I mean the collision is working and everything
Should I just move rb.MovePosition(holdPosition); into FixedUpdate?
i have no idea if it's that simple
because I didn't look closely at your code
but MovePosition should only be used in FixedUpdate
much like most physics operations
I'll try it rq
also make sure to enable interpolation on your Rigidbody
Good idea, also moving into FixedUpdate didn't fix the jittering
Small issue lol
Also if I run into a wall while holding the cube and turn around then I go flying
Press play in Unity before you start recording 😄
It may be enough to disable the collider on the cube when picking it up, do the animation to hold it in the correct position, then re-enable the collider
I originally had the collider disabled when the cube was picked up but it allowed it to be passed through walls
you are working on the allocator?....
assume overlap==covers the whole rect requested (otherwise you need to "subtract" the area from requested rect and runs dfs on neighbors, it is much complicated)
then it will generate bound (free Rect in capital letter and requested Rect in small letters)
X_MIN---x_min---x_max---X_Max in x-axis and
Y_Min---y_min---y_max---Y_Max in y-axis (note that the rect maybe deformed after generation
you dont need to do any checking, the four new rects generated is
min max
X_MIN,Y_MIn x_min,Y_MAX
x_min,Y_Min x_max,y_min
x_min,y_max x_max,Y_MAX
x_max,Y_MIN X_MAX,Y_MAX (you will notice than max x, y always > min x, y)
just draw a diagram and try it yourself to see how you can use (X_MIN) (Y_MIN) (X_MAX,Y_MAX) in free rect and (x_min,y_min) (x_max,y_max) in requested rect to allocate space in refill the free list
Can be assumed as allocator 😅
This is for area pooling (I need to occupy area for a while and then free it)
I do checking, because I don't need empty rects
but I guess, code can be cleaner with other checks
sorry, but your layout of new rects is confusing
but I got the idea, I get it how to calculate them
if multiples adjacency free rect can used to allocate:
after each overlaps the requested AABB only generate <= two new AABBs and you just keep doing that until no new AABB is generated (ie the free rect fully cover the AABB)
Thanks! I got it to work
void FixedUpdate(){
Rigidbody2D rb = null; // Declare rb here
Vector3 holdPosition = transform.position + (spriteRenderer.flipX ? -transform.right : transform.right) * holdDistance;
if (heldObject != null){
rb = heldObject.GetComponent<Rigidbody2D>();
}
if (heldObject != null)
{
// Make the object float in front of the player
if (rb != null)
{
rb.MovePosition(holdPosition);
rb.velocity = Vector2.zero; // Set the velocity to zero
}
}
if (rb != null){
if(rb.transform.position == holdPosition){
if (isHolding){
Collider2D col = heldObject.GetComponent<Collider2D>();
if (col != null)
{
col.enabled = true;
}
}
}
}
}
idk how to type it: 0 is free rect and 1 is requested rect
000
001 1
11 here a 1 and 11 AABB are generated
000
011
11 only 11 AABB is generated
011
011 fully covered
2D version of MovePosition seems to use velocity actually
Moves the rigidbody to the specified position by calculating the appropriate linear velocity required to move the rigidbody to that position during the next physics update.
yeah we did a bunch of experimentation with this a while back and I remember 2d being different from 3d but I forgot the details
do you mind looking into this piece as well?
This Recombine is supposed to combine rects that can be combined into one. But it seems like it's faulty and I'm not sure what's wrong.
private struct Sorter : IComparer<RectInt>
{
public int Compare(RectInt x, RectInt y) => x.xMin.CompareTo(y.xMin);
}
private void Recombine()
{
// Sort the oldRects based on their xMin values
freeRects.Sort(new Sorter());
// Iterate through each old RectInt
foreach (var rect in freeRects)
{
var combined = false;
// Try to combine the rect with the last new RectInt in the list
if (_tempRects.Length > 0)
{
ref var lastRect = ref _tempRects.ElementAt(_tempRects.Length - 1);
if (rect.yMin == lastRect.yMin && rect.yMax == lastRect.yMax && rect.xMin == lastRect.xMax)
{
lastRect.xMax = rect.xMax; // Extend the width of the lastRect
combined = true;
}
}
// If the rect couldn't be combined, add it as a new RectInt in the list
if (!combined)
{
_tempRects.Add(rect);
}
}
freeRects.CopyFrom(_tempRects);
}
oh, me stuped
forgot to clean temp rects
also seems like it doesn't do very good job either
tons of 5x5 rects are not combined, when they should
there are two cases
AA
BB
and
AA BB
this only do the second job
I am trying to assign a material to a 3D object plane but the plane is still transparrent for some reason. Anyone help please?
sorting may not be a good way to find neighbors AABB (the best way is k-d tree)
on every AABB->look for adjacency AABB with width==itself.width (or height)
and keep looping until no more combination happens
it may not be completed with just one loop: consider this
AA
BC
first you need to combine B and C to be DD
AA
DD
then combine AA and DD
not a code question
performance may be concern here
this is supposed to happen with 1k+ rects
as in, about a thousand of "allocations"
hmm, also not exactly sure what you mean
by width you mean extremums?
oh, you're not
ok, this starts to make "some" sense 😅
this.min.x==other.min.x && max.x as well, since other must be the rect nearby
loop until no more combination:
for each rect in free list->find all its neighbor and combine (remove them from list too)
three loops, i am thinking how to do it in k-d tree
goto parent node->see if another child (since each node in kd tree have two children) can be combined with itself, do this recursively? i think the algorithm should be similar to quadtree
so you suggest to loop all free rects against all free rects?
double loop basically
you may end up with a data structrue like this
a k-d tree with a free list (it is double linked list since you have to update previous and next child node) to connect all available child AABB in k-d tree in green (they can be used to allocate space) while the node in red means allocated space
and causes many, many bugs
uuugh, I'd rather go with less efficient, but simpler approach 😅
I thought you just had a rectangle (width and height) that you wanted to find an empty spot for, but it appears you already have a spot picked out and trying to find what existing rects overlap with it?
no, I don't have spot picked
except
some are indeed picked already
then just for each rect: loop through all other rect and try to combine them (remember to remove the rect that is combined)
basically: existing world preallocates some rects forever. And then dynamic world allocates/frees dynamically.
Those are two different problems that require two different solutions. I missed some of the conversation, do you have a different method for dealing with the dynamic world?
It's not so important that this part (preallocating some rects) is fast, because it only happens once when the world is created, right?
I just treat dynamic world same as static world
I find the free spot
and Set it just I like do with static world
That complicates it, though. Because you probably already looked to the free rects to find a free spot, and then you need to do it again when you call Set.
well, true
allthough
it's oposite of complication - simplification at a cost of performance
Hmm, I think I'm missing something ehre
private static bool CanBeCombined(RectInt aRect, RectInt bRect)
{
if (aRect.yMin == bRect.yMin && aRect.yMax == bRect.yMax && aRect.xMin == bRect.xMax)
{
return true;
}
if (aRect.xMin == bRect.xMin && aRect.xMax == bRect.xMax && aRect.yMin == bRect.yMax)
{
return true;
}
return false;
}
oooh, right
i believe the clean up must be done after iteration otherwise the index would go wrong or some Rect will be skipped, may not true
Now this should be right
if (aRect.yMin == bRect.yMin && aRect.yMax == bRect.yMax &&
(aRect.xMin == bRect.xMax || aRect.xMax == bRect.xMin))
{
return true;
}
if (aRect.xMin == bRect.xMin && aRect.xMax == bRect.xMax &&
(aRect.yMin == bRect.yMax || aRect.yMax == bRect.yMin))
{
return true;
}
ah skip if i==j as well
I did slightly opposite
for (var i = freeRects.Length - 1; i >= 0; i--)
{
var aRect = freeRects[i];
for (var j = i - 1; j >= 0; j--)
{
ref var bRect = ref freeRects.ElementAt(j);
if (CanBeCombined(aRect, bRect))
{
freeRects.RemoveAt(i);
bRect = new RectInt
{
xMin = math.min(aRect.xMin, bRect.xMin),
yMin = math.min(aRect.yMin, bRect.yMin),
xMax = math.max(aRect.xMax, bRect.xMax),
yMax = math.max(aRect.yMax, bRect.yMax)
};
}
}
}
and maybe a bit more efficient?
yes
still something is wrong
that blue and green haven't combined after 3 attempts
and I do 3 loops of those loops above
after remove aRect it should be break since aRect no longer exists
it is combined to bRect
the outermost loop (not the i loop) should break only if there is no more merge, it is indefinite
try to add a boolean as mine version to see if it works
the upper limit should be number of rect btw since you may have something likes:
https://www.elegantthemes.com/blog/wp-content/uploads/2019/06/Ratio-1024x648.png
nightmare
oh it can be finished within one iteration if you are lucky enough, the area sorted by decreased order
ok, let's see
I guess, I'll have to move it to job
nah
green and blue are still here
private void Recombine()
{
var combined = true;
while (combined)
{
combined = false;
for (var i = freeRects.Length - 1; i >= 0; i--)
{
var aRect = freeRects[i];
for (var j = i - 1; j >= 0; j--)
{
ref var bRect = ref freeRects.ElementAt(j);
if (CanBeCombined(aRect, bRect))
{
freeRects.RemoveAt(i);
combined = true;
bRect = new RectInt
{
xMin = math.min(aRect.xMin, bRect.xMin),
yMin = math.min(aRect.yMin, bRect.yMin),
xMax = math.max(aRect.xMax, bRect.xMax),
yMax = math.max(aRect.yMax, bRect.yMax)
};
break;
}
}
}
}
}
Here CanBeCombined
if (aRect.yMin == bRect.yMin && aRect.yMax == bRect.yMax &&
(aRect.xMin == bRect.xMax || aRect.xMax == bRect.xMin))
{
return true;
}
if (aRect.xMin == bRect.xMin && aRect.xMax == bRect.xMax &&
(aRect.yMin == bRect.yMax || aRect.yMax == bRect.yMin))
{
return true;
}
return false;
I feel like my checking algo for combination is awful
yes since you cant find nearby rect efficiently with list, i have no idea why the checking from green or blue is skipped or returning false, maybe log it yourself first to see what really happens when length==5
is that the one?
I was always thinking that the splits would be recorded, like in a spatial tree, so it would be easy to recursively iterate over it, combining empty pairs.
nah, it looks like cyan
hmmm. Is my algo wrong alltogether?
yep
I think something is wrong with cutting out the center part
and I calculate leftover rects
wrong
the four rects generated by my approach should be
124
1C4
134 where C is centre
i think you want
122
1C4
334 ?
sorry, I totally don't get your layouts. I just do math with this picture 😅
ok, I think I fixed it
ok, I think it's good now
3 "static" positions are cutout correct
and every new area is merged correctly as well
the only bit left for "perfect"
is calculate position for new rect closest to center
Hi. Does anyone know a way to make like a fixed joint component but that it can compress but not extend?
use Unity's Fixed Joint Component and clamp the velocity
uhhh...why clamp the velocity...?
also how would that make it be able to compress but not extend?
let's say you have a lever and only want it to go to the left, if the velocity.x is < 0 than it is trying to move to the right, so you reset the x velocity back to 0. You'd need to rotate the velocity to match the angle between the anchor and the object though.
So I'm trying to get my language typing game to recognize foreign input... when I put in foreign characters it won't correctly detect as intended. Could it have something to do with string?
private void CheckInput()
{
if(Input.anyKeyDown)
{
string keysPressed = Input.inputString;
if (keysPressed.Length == 1)
EnterLetter(keysPressed);
}
}
What does this mean?
it won't correctly detect as intended
what is happening and how is it different from what you expect
So right now it works for English characters but when I try it with Japanese it won't work
Length of Unicode characters can be longer than 1
What's the point of checking the length anyway?
What does "won't work" mean?
What happens, and how does that compare with what you expect to happen?
there is a lot you will have to learn about foreign languages!
Oh interesting... yeah I'm not sure I followed a tutorial haha
I didn't know unicode characters can be longer than 1
wdym?
Modern extension to classic 2003 article by Joel Spolsky
hey everyone, im trying to make a bullet script that i can inherit from to make funky bullets, but i barely know what inheritance is, i know some things but not enough to know how to make such a script
is there anyone that can help me with this?
Inheritance can work, but it's not always the answer.
i barely know what inheritance is
What makes you think inheritance is a good solution to your problem?
cause im making a want type weapon, with 3 states, witch each 3 different working funky bullets, and setting up a base for each bullet to use would work better wouldnt it?
just making 3 different bullets
not much changes between them exept some of their properties, like 1. the bullet kind of homes in on the enemy, 2 the bullet is piecing precise and fast, while the 3rd one would be a short raged damage dealer
all with the same "bullet" properties right?
I would make one Projectile script with basic properties like damage, etc.
You can then just attach other components to particular bullet prefabs that modify the behavior as desired
I don't really see a huge benefit to inheritance here
ya think? i don't really know how to make those other components work together with the bullet though, and thats why i thought inhereting would be good
Basics of Unity:
Projectile p;
void Awake() {
p = GetComponent<Projectile>();
}```
if you even need that
the other script can likely just handle movement for example without even caring about the fact that the Projectile component is there
my brain isnt breaining rn, im a little lost, so just make a bullet script and then a second script that does the properties of the homing for example?
yes
the bullet script needn't do much at all on its own
just have damage amount on it for example
maybe give it a starting velocity
Assuming you're using a Rigidbody
probably not, just a collider, if it hits the wall it just dies
so Unity isn't allowing me to enter into Japanese IME mode... anyone have any thoughts as to what is happening?
moving things with colliders need Rigidbodies to handle collisions properly
ohh ye u right, my bad
I can enter into Japanese mode but it won't let me switch the IME (Input Method Editor)
thnx tho!
This is how the keyboard should be able to switch to in-game...
Could it have something to do with Input.inputString?
private void CheckInput()
{
if(Input.anyKeyDown)
{
string keysPressed = Input.inputString;
if (keysPressed.Length >= 1)
EnterLetter(keysPressed);
Debug.Log(keysPressed);
}
}
Maybe it doesnt support foreign character input?
Ahh... Only ASCII characters are contained in the inputString.
Anyone know of an alternative to this?
Please help. I'm trying to get a better understanding of code architecture. Both code which repeats, and classes which do too much are considered bad practice, right?
So... Let's say I want to make a damage system. For this I create
an IDamagable interface. Most of classes which implement this interface, will most likely reuse the same code for the damage. This seems like repeating code, which is a bad practice, isnt it?
Another way to go about it is to create a base class which contains a Damage method, and then when some object needs it, just inherit from it. But then, I need to add a "use" functionality (ability to be interacted with by the player). I add a use() method to the base class. Now all of the inherited classes have the "use" method even
when some dont need it. Isnt this also bad practice?
Which one of these is a better solution? Is there a rule of thumb for my monke brain which determines when to use interfaces and when to use inheritance? Is there a better way I'm just not thinking about? (or do I have a wrong understanding of inheritance and interfaces?)
If the implementation will be very different, you want an interface
if implementation is (almost) identical, you want inheritance or composition
Example: In mario, spawners could be fixed spawnpoints, pipes, blocks. They all share a common behaviour (calling spawn and needing to be notified about death/despawn). But what they actually do when Spawn is called is totally different. You want an interface here
Example; Goombas, koopas, and piranha plants all do a similar thing when taking damage. (play a given death animation tied for it etc). Taking damage here should be handled by composition
Thanks for the answer, will keep this in mind. One more question. Is a health component less desirable in unity? I seem to encounter inheritance and interfaces for things like damage systems etc.
I would use a status component
One component that just handles all status (HP, status effects, modifiers etc) as a central point of contact. This Status component should be able to modify its own fields when information is passed onto it
should not have complex logic. Just basic accessors to read and write
and a little bit of logic, if the information passed into it is very spoonfed
If you need to do special stuff in response to damage, consider having a common "damageable" component that raises various events
I've gone completely bonkers in my game. Entities just have a pile of "vitals". So, as far as the C# is concerned, they don't have "health", "stamina", "mana", etc.
Damage is a list of vital kinds and the amount to change them by. Entities that lack a certain kind of vital ignore damage they can't take.
Entities monitor their vitals and can enter special states (if the current state allows it) when they hit zero. So, if an entity's stability vital goes to zero, it plays a stumble animation.
...gotta admit, sometimes it's really nice to be able to just write if (entity.health <= 0), lol
this is an extreme composition-based approach
Most of my entities have the following components:
-EntityDataHolder: holds SOs and references to key bits of data inherent to the entity needed for general game logic.
-SpawnedEntityHandler: Handles spawning, despawning, and death. It’s the main link between the entity and whatever ISpawner spawned it in.
-ObjCollision: Takes in collision callbacks and processes it in a way that can be readily used with EntityData to perform different types of logic checks.
-GenericEntityLogic: holds entity status, and processes information (usually from ObjCollision) to check for damage requests.
not all entities have all those components.
but every entity has an EntityDataHolder so we can know wtf it is and does during runtime
mine usually stems like IObject -> IEntity -> IPlayer
every single game I've made recently is literally just Entity
My EntityData just has a bool for isPlayer
I did something a little more elaborate
Thanks a lot for in depth info ❤️
but same idea
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Localization;
[CreateAssetMenu(fileName = "New Entity Spec", menuName = "Entity Spec")]
[JsonConverter(typeof(IdentifiableConverter))]
public class EntitySpec : Identifiable
{
public LocalizedString label;
public LocalizedString description;
public bool isPlayer;
public bool isBoss;
}
i meant a heart, not lungs
lol
I have different specific components for different types of motion, and a specific entity script can turn them on/off like a FSM
but thanks 🫁
yeah, that's where the Locomotion comes in
it converts the direction of motion the entity wants into actual movement
I'm thinking I'm going to have an entire locomotion component for stuff like climbing a ladder
i mean I have several different generic scripts that take full control of enemy movement behaviour. Then a specific script that lets me swap between them
like RailMovement, GenericEnemyWalk, KinematicFalling components. Which are all generic.
Then imagine GoombaBehaviour turns them on/off, so at most one is on at a time
understand?
each MonoBehaviour is a complete package, more or less
btw I now have a new PhysicsMover component, which is basically my own wrapper around rigidbody API
my manual simulation is coming along nicely in time to show family for thanksgiving
idk if you were there when I mentioned, but in case anyone might be interested in my physics engine:
Pros:
-Reference frame support (ie parenting RBs is fully supported)
-Easy to customize force relationships (eg x sends force to y under z circumstance)
-Easy to write your own effectors
-Built in grounding, ground movement
-Would be Open Source
Cons:
-No rotation
-Certain collider types must be tied to CompositeCollider2D.
-No joints
-Only simulate one main collider per moving obj.
Neutral (neither pro nor con):
-Force does not transfer through objects (Newton’s cradle would just hard stop at first collision).
-Special collisions: Collisions try to maintain ground speed OR vertical speed. (so horizontal speed doesn’t depend on slopes, and you cant change jump height by hitting slopey walls).
-Very sequential simulation: All moving objects get evaluated in a specific sequence, where you can alter the ordering.
@heady iris sound interesting/worth sharing?
I’d call it a polite algorithm: Move colliders on “dynamic” rb assuming everything else in world is static. So one RB can never push another unless it is actually fully kinematic (or you use a script to make the illusion outside of physics step)
this sounds more like a highly customized mechanic for your game, rather than a physics engine.
Force does not transfer through objects
sounds very not physics-like
so, my game world breaks several laws of physics, like Newton’s 3rd law and conservation of energy
it mostly allows things to bump into each other, and try to resolve overlaps
and be in well defined reference frames
that last one is basically impossible in normal Physics2D
trying to call a coroutine on the player script that inherits monobehvaiour, ienumerator is defined within the Sliding state for my player movement - does this imply that I need to move the coroutine to the player controller script itself? I'm currently trying to call it like this:
Character.StartCoroutine(nameof(slideTimer));
coroutine is defined as below:
public IEnumerator SlideTimer()
{
yield return new WaitForSeconds(_maxSlideTime);
_isSliding = false;
}
slideTimer is not the same as SlideTimer - do you have a variable named slideTimer? You're referring to it by mistake in nameof here
This usually means you're trying to start a coroutine on a deactivated object
oh
also that
yeah
you used the wrong name
why use nameof at all?
why not just StartCoroutine(SlideTimer());?
because I need to also use StopCoroutine unless I am completely missng something here
just spotted that, I need to reference it
or better yet put a function on the script:
public void StartSliding() {
StartCoroutine(SlideTimer());
}``` and call that
you are missing something
nothing about stopcoroutine requires using the string version of StartCoroutine
got it, and then to stop the coroutine I'd just do slideTimer = Character.StopCoroutine(SlideTimer()); right?
that makes more sense
my bad
my mind is completely ignoring the most blatant solutions lmao
yeah this time no errors, thank you :)
same here: always. KISS is really really hard
it be like that sometimes
is there any easy method I can implement a coroutine where I pass in a boolean and then after the waitforseconds is over I can reverse that bool value? kinda like with c++ when you can simply just assign a reference like &[boolToAffect] - I know that functions have got the whole out prefix but still
you cant use out or ref if im remembering correctly. easiest way is make the bool global and then change it from the coroutine directly
or create a class with the bool and modify it inside the class
i don't believe that coroutines can use out or ref parameters
Yep, as enumerators compile into a big state machine (an entire class) you can't use out nor ref
yeah its seeming that they cant
I could use a class tbh with bools which will be scalable but its a premature thing to do with where I'm at in my project
so bawsi's class suggestion would be the easiest way. or you can pass an Action<bool> to the coroutine and just pass the bool's value when you invoke that action
how would I go about using a class and then also implementing an ienumerator for it
no instead of passing a bool to the coroutine you pass an instance of some class that contains the bool. since the class is a reference type any variable referencing that instance will be able to access the bool's updated value after the coroutine changes it
i still think that passing an Action for a callback would be the cleanest way to handle it though so you won't just be polling the bool for changes, you would instead have a method that just reacts to the change when the action is invoked
I get it but I don't at the same time
what part of that do you not understand?
so what I ideally want is
bool1 = false
bool2 = false
bool3 = false
starttimer(bool1)
after the timer ends the bool I've passed through will now be true
but a callback / class doesn't seem to kinda explain to me how I'd implement that within a coroutine
for the class you just do something like this:
public class TimerBool { public bool TimerRunning; }
//in your monobehaviour
private IEnumerator StartTimer(TimerBool timer)
{
//do you stuff
timer.TimerRunning = true;
}
and since TimerBool is a reference type, anything referencing that instance will have access to the same bool variable inside of that class
yep. this is what the Volume framework does, for example
it has a bunch of classes that hold a value
You can get more elaborate with it, too. For example...
public class TimerBool
{
private bool _value;
public bool Value
{
get => _value;
set
{
if (_value != value)
{
OnChange?.Invoke(value);
_value = value;
}
}
}
public event System.Action<bool> OnChange;
}
now you can subscribe to changes to this shared value
although it also really depends on the actual purpose of this for the best way to handle it. For example, if it is literally just for a timer that delays something from happening, you can just pass an Action and forget about the bool at all, then just invoke the action when the coroutine has finished instead of just flipping a bool value
then explain exactly wtf you are actually trying to do
https://xyproblem.info/
Asking about your attempted solution rather than your actual problem
ok right
and that error is pretty self explanatory
so my movement stuff follows a finite state machine layout
I want to have bools to check if the cooldown is over for certain things e.g.:
- canSlide
- canJump
- canWallrun
etc etc
and instead of having to do a coroutine for each one and their cooldown length, I'm wanting a single coroutine where I can pass through the boolean I want to be affected alongside the duration the timer runs for
so if I were to say, want to enable sliding
then
I'd like something like:
private IEnumerator movementTimer(bool boolToAffect, float timeToTake)
{
yield return new WaitForSeconds(timeToTake);
boolToAffect = true;
}
but with the above definition, that'd only affect the value of the local var due to it being a reference and not it being the physical value
basically wanting an equivalnce of:
private IEnumerator movementTimer(ref bool boolToAffect, float timeToTake)
{
yield return new WaitForSeconds(timeToTake);
boolToAffect = true;
}
which isn't doable due to how coroutines / ienumerators work
okay so both of the solutions that were suggested would solve this
You will need to replace your bool fields with BoolCountdown fields.
if you want to go that route
Personally, I wouldn't even bother if you have such a small set of fields that need toggling.
Or I'd just make an enum type to control things.
this is early into the project, there will be a lot more further down the line
along with a switch statement to target the relevant field
if i was you id replace bool fields with BoolCountdown fields @untold siren
I know you're trying but that still doesn't make sense to me lol
Actions might be a bit easier and more versatile.
private IEnumerator Cooldown(Action cooldownComplete, float time)
{
yield return new WaitForSeconds(time);
cooldownComplete?.Invoke();
}
then just use it like
StartCoroutine(Cooldown(() => canSlide = true, 0.5f));
You could even reuse that for things other than just flipping a bool's value too
you see that one makes sense to me 
where DelayedSet starts a coroutine that waits for the specified time, then decides which field to set based on its first argument
however 
Character.StartCoroutine(Character.BoolCooldown() => Character.canSlide = true, 0.5f);
that syntax is all kinds of messed up
lmao wdym
Character.BoolCooldown() is invoking a method on Character named BoolCooldown
then the parser crashes into =>
yeah they just missed the opening ( for the anonymous method so it made the entire thing look weird
oh, is this meant to be
Character.StartCoroutine(Character.BoolCooldown(() => Character.canSlide = true, 0.5f));
I'd hvae to see whatever BoolCooldown is, I guess
yeah i think they took my suggestion of passing an action
and I see now that Character is a variable, not a type name
public IEnumerator BoolCooldown(Action cooldownComplete, float timeToTake)
{
yield return new WaitForSeconds(timeToTake);
cooldownComplete?.Invoke();
}
I would name it something other than BoolCooldown though because it doesn't have to be a bool anymore
This is basically just unity's Invoke method but with delegates instead of reflection to find a method
got it working, thank you guys
for checking new input system stuff I can replace:
if (JumpAction.triggered)
isJumping = true;
if (SlideAction.triggered)
isSliding = true;
with something like:
isJumping = JumpAction.IsPressed();
isSliding = SlideAction.IsPressed();
right?
If the InputAction is a "button" type, then that'll tell you if it's currently pressed, yes
got it, thank you
And more generally, any pattern that looks like this
if (condition)
thing = true;
else
thing = false;
Can be shortened down to thing = condition;
well, these are actually two different things
the former sets isJumping to true if you trigger the action
and does nothing otherwise
the latter sets isJumping to true if you're holding the button and to false if you aren't
Those are not equivalent. The latter resets the variable the moment you let go.
They probably have other conditions that check for button release somewhere below
assuming to much of me
in the process of getting this stuff implemented I completely forgot to add the button release check
only just realised now that I'm implementing cooldowns
Localization
Heya ive run into a bit of a wall. Say Im making a game that has "weapon groups". There are six total that the player can assign to any button. This comes into the form of a bool[6]. Every weapon will have it stored. So the question is. How should I go about saving all the weapon groups to a file to load and assign to the appropriate weapons later?
I don't understand your design. Are you saying that each weapon can be assigned to fire when one of six buttons are pressed?
e.g. weapon 1 fires when buttons A/B/C/D are pressed and weapon 2 fires when buttons C/D/E/F are pressed
Yep
I just need to store what the player sets
Are the weapons fixed, or can you also customize which weapons you have?
Im thinking json might work. But ive never messed with it, so could I use it or somthing simaler?
yes, you ought to be able to serialize this data into a JSON file, then read it back in later
Eatch weapon can be changed out for another in the same type, Like one point can be all energy type (lasers, Particle cannons, ect) and another be balistic and so on
okay, so you'll need to remember both which weapon is in the slot and which groups the weapon has been assigned to
Alright then Ill take that route as ive seen lotsa talk bout it
I'd suggest creating a save data class
You'll save the game by creating an object and putting data into it
[System.Serializable]
public class SaveData {
public List<WeaponData> weapons = new();
}
[System.Serializable]
public class WeaponData {
public string id;
public List<bool> groups = new();
}
It could look like this, for example
This would be seprate from the classes you have already
You wouldn't be trying to serialize your Weapon class directly
hey lads, can anyone help me with this
1/ A script that will be added onto an object.
(Addendum : The script will have a float variable named Duration)
2/ It will check if object already has the same script (except itself).
3/ It will proceed to increase the previous one's Duration and delete itself.
Many thanks in advance
2: TryGetComponent
3: if found existing component, Destroy(this)
Why would the new script change the old one's duration though?
Is the idea to like merge duplicate components?
Is it like a status effect/buff or something?
You can do it with trygetcomp like I said but it would be good to have a script that manages that stuff
And keeps current effects in a list
true, I'll look forward into it
working wonderfully, appreciate the help mate
have a nice day
Np, you too 👍
So Im trying to convert English letters to Japanese ... what's the best loop to go through the input and replace the respective characters?
private void CheckInput()
{
if (Input.anyKeyDown)
{
string keysPressed = Input.inputString;
// adding character to the string
japaneseText += Input.inputString;
Dictionary<char, string> kana= new Dictionary<char, string>
{
{'a', "あ"}, {'i', "い"}, {'u', "う"}, {'e', "え"}, {'o', "お"}
//{"', "か"}, {'ki', "き"}, {'ku', "く"}, {'ke', "け"}, {'ko', "こ"},
// Add more mappings as needed
};
if (keysPressed.Length >= 1)
{
//EnterLetter(keysPressed);
EnterLetter(japaneseText);
}
}
}
Define the dictionary outside of the function if possible 
Maybe use a serialized dictionary asset from the unity store - there are free ones.
Is there any reason you're not using an InputField? OnValidateInput would make this a simple switch statement or TryGetValue return
Though I suppose not if you're doing the second line with dual characters
For that you'd better be using a stringbuilder and a loop
I have a script to select gameobjects. It selects them when i click on the screen and it sends a raycast and returns the hit gameobject. I have 2 joysticks (canvas) and some ui elements (ui toolkit) on my screen. If i click on them, the raycast shoots and selects the gameobjects behind them. Any idea how to prevent this?
So Im tryng to make a reflector in unity 2d and i am unsure how to go about it
My initial plan was to have a prefab particle and just add some collider to it
And when projectiles hit this collider they move at the opposite direction
The problem is the collider of the particle is a bit weird
since its a bit rounded, the way the projectile moves after getting reflected is not as intended
I was also planning to add a sperate collider but the issue i find is that the collider does not follow how the animation looks
I have two scroll areas side by side. The left one cuts of the top element the right one works correctly.
Their setup is identical. Please Help
I have tried moving the "ReportCards" with the Rect tool but it just snaps back.
you need to get rid of these content size fitters first
they might be causing unreliable behavior
The content size fitter should go as high up as possible
basically, if your parent has a Layout component, you should not have a Content Size Fitter component
it should go on your parent instead
Had tried that, that doesn't fix unfortunately
⬆️
Your scroll areas should have a layout component on them.
You need an unbroken chain of Layout components all the way down
Otherwise, the child components won't be able to ask for the appropriate amount of space
I might be mistaken. Let me check that.
ah, yes, I see how I've done this before
gimme a few minutes
Here's your problem.
Your left scrollrect has the wrong viewport
Also, I put my content size fitters on the child of the Viewport transform, so it looks like this
- Scroller <-
Scroll Rect- Viewport <-
Mask,Image- Content <-
Content Size Fitter,Vertical Layout Group
- Content <-
- Viewport <-
also, if you have other questions about this, they should go into #📲┃ui-ux
Camera cam = globalPlayerManager.GetPlayerCamera();
var objRotation = Quaternion.LookRotation(obj.transform.position - cam.transform.position);
while (cam.transform.rotation != objRotation)
{
cam.transform.rotation = Quaternion.Slerp(cam.transform.rotation, objRotation, 2f * Time.deltaTime);
}
Is this good code for smoothly looking the camera?
use cinemachine
I guess it works, but yes, you should consider using Cinemachine for camera control
its one of those, why reinvent the wheel if someone made these features already
well I like programming things myself since I'm a solo programmer, feels lazy
I like reinventing the wheel to understand the wheel
if you're going to use Slerp, check https://unity.huh.how/lerp/wrong-lerp
your code will behave very differently at different framerates as-is
If I use cinemachine I use it specifically for these specific cases with smoothing and not having to deal with jittering
seriously its butter smooth
OH MY GOD thank you, this one cost me 1-2 hours. Thanks for spending the time. ❤️
I still find plenty of ways to cause jittering 🫠
np!
its one of those things you think you wont need them until you start making more complex camera systems like the one Clear Shot makes a breeze
how easy is cinemachine to integrate into an existing project
the deoccluder has been very useful
my code is crashing Unity
and I don't feel like figuring it out
plug in a target and done
Nothing wrong with that, I dont get it when people insist you must use cinemachine
I mean if you enjoy coding features people already made better, more power to you
if I see someone with a flat tire, I'm going to suggest they put on the spare instead of trying to build a new wheel out of lego
I prefer having smarter people make the features I need and I just implement them
to each their own
i just really like using cinemachine
it solves a complex problem so that i can make my dang game
100% if you just need results, thats why cinemachine exists
Doing camera stuff is a great way to learn about order of execution and possibly physics if thats involved
sure. valid point never said otherwise
I got to learn about execution order when getting Cinemachine to play nice with third party plugins 😛
camera stabilization is a pain
but if you've a flat terrain then anything is fine lol
Oh yes, there will be pain 😄
my physics system is using non-alloc .Cast methods for casting, and it gives me options for both arrays and lists... does it really make much difference?
array forces me to set a max size in advance. List auto-resizes.
!vc
Unity Version Control
Git
Get the latest .gitignore file from here. It should be placed at the root of your Unity project directory.
if you're using non-alloc usually you'd already have a set array capacity so you don't need to recreate it every time you need more info.
like, the idea is to set a large capacity
i think that the query will returns only array.length elements if you use array and you will miss some XXXInfo.
idk why it does not take a ref array into it, since it is the same as list
it'll populate up to the max, but the idea is to add a larger buffer size than you need
mem is cheap anyway ;p
List can work too as long as you don't trim the excess. Create a small buffer of elements and then let the list decide the capacity if it needs to extend over the max.
I don't see a Cast() method on lists. Are you looking at the LINQ method?
It's definitely from LINQ yes
That will mega-allocate for sure
i think he means his physics system calls the Physics.XXXCast
Oh, I see
I thought you were talking about casting arrays and lists
That makes more sense
I'm assuming it's this method
https://docs.unity3d.com/ScriptReference/Collider2D.Cast.html
ah, and this one lets you use both static arrays and lists
Using List seems more convenient, and it won't reallocate unless it actually needs to
I usually reuse a single static List for all physics queries across my entire project 😆
my class have their own static buffer
it'd be really nice if the other physics methods could also take a list
Collider2D.Cast
i tried arrays before. Moved to lists. Now idk if I should optimize by going back for some choice arrays
I would not expect much of a difference
figured. worth asking
Does Unity support use of DLL's built with C#10?
I know Unity itself doesn't support C#10, but I'm not sure for DLLs
I would assume not, but idk for sure
unity barely supports C#9
CompositeCollider2D.edgeRadius only seems to impact the collider when it is in Outline mode. Is there a workaround to get it to work with Polygon mode?
Hi,
I have a wierd error that I havent come across before.
I have set up a prefab and a runtimeIntilizeOnLoad on a static class so that all my necessery objects are loaded no matter what scene I use. This is all working as inteded.
However when I load a scene for a second time it seems like these cant find in the scene.
I have a simple funtion
GameObject.Find("playerParent").transform)
that is beeing called when
(SceneManager.GetActiveScene().isLoaded)
This works the first time the scene is loaded but not the second.
I have never had this problem before and therefore im thinking that the fact that I use the runtimeInilize somehow is to blame
The "playerParent" is visable in the inspector but I still get a nullref error
I would not call GameObject.Find
whats a good way for making a lot of different areas of the world respond when clicked?
like if I have an image, and I want something different to happen depending on where you click it, creating a ton of buttons or collidiers does not seem like the correct solution
that method is a noob trap
I would make a monobehaviuour that reads mouse position when you click, then raycasts there to check if you touched something
I remember I was causing thousands of lag frames because I was calling Find in update on hundreds of objects and never looked at the profiler 💀
I fixed that
maybe voronoi map
.Find is a noob trap
yeah, I was thinking of this, but im not sure how to use one
you want to get the reference normally, not with .Find
Yeah I think this is the only place I use it in the project, figuered that it was only called one when the scene was loaded so it wasent that big of a deal
yeah that should be fine
but dont call it a lot
and if you start having perf issues it should be the first thing to optimize
I have a Singleton that has references to key gameobjects. This singleton is destroyed on load
smort
like, WorldGameObjectCentral has direct references to: the main Grid for my game world, my player gameObject, the goal flag object, the starting position object
just a few really critical and static things
Don't cross-post.
One channel per question please
Ok so the singleton is in the scene and gets loaded and destroyed with it then that is refferenced rather than the gameobjects themself?
depends on the regions too. maybe you can use a raycast as well to check coord /color of texture at point or something?
so depending on color = certain region
but if its a singelton it cant be on a gameobject
so how does that work?
or is it just a static refference?
static instance of the singleton
unity doesnt really have traditional DI system , singleton here you still need a gameobject somewhere
whats the key differences between Awake and Start and which one should I use?
Awake is best for initialization
I suppose think of it like a constructor that runs at least once
so why wouldnt i use Start
even unity says
Note: Use Awake instead of the constructor for initialization, as the serialized state of the component is undefined at construction time. Awake is called once, just like the constructor.
https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html
because lets say you have a singleton happening then you have another script that subscribes to something on that singleton, if you put both in awake/start you get a null ref at some point because order is not guaranteed, having awake doing Init singleton first and then others sub on Start/OnEnable you guarnteed no null ref from Singleton initialized in awake.. Hope is not confusing example..
no, that makes sense
😅 the link in docs explains a bit more also some key differences
like when objects are disabled
etc
Ok, thanks, I'll give it a try. It's still wierd that I get a null ref even though it exist in the hierarchy
I haven't seen your post, which line is null ref
something interesting also if you aren't aware of this
https://docs.unity3d.com/Manual/ExecutionOrder.html
its good to know how the scripts are working behind the scnes in unity events
Hi,
I have a wierd error that I havent come across before.
I have set up a prefab and a runtimeIntilizeOnLoad on a static class so that all my necessery objects are loaded no matter what scene I use. This is all working as inteded.
However when I load a scene for a second time it seems like these cant find in the scene.
I have a simple funtion
GameObject.Find("playerParent").transform)
that is beeing called when
(SceneManager.GetActiveScene().isLoaded)
This works the first time the scene is loaded but not the second.
I have never had this problem before and therefore im thinking that the fact that I use the runtimeInilize somehow is to blame
The "playerParent" is visable in the inspector but I still get a nullref error
can you show the exact error / full stack
Sorry can't atm, on my way from work now so only on my phone
ah well it would be easier to debug if we can see more info
But hopefully a singleton with a ref might solve the problem
Find method are to be avoided
Yeah, totally understand that, thought it might be a gotcha with having initialize on load and system prefab
does the object still exist after you load the scene again?
or are you calling DontDestroyOnLoad on the loaded object?
Yeah it's beeing loaded with the scene and can be found in the inspector
I have a don't destroy on load on my system prefab that I instsciate with a static class. So the object using the find is don't destroy on load
oh, I see; the object you spawned is trying to find a scene object
The object beeing spawned is basically a gamemanger, scenehandler etc.
This is beeing spawned when the first scene is loaded and the root object of the prefab had don't destroy on load.
Then when a certain scene is loaded, it looks for a game object ("playerParent" ) that Is suppose to be used as a parent for other objects that are instanced in that scene
why does only directional light produce light and not spotlight? is there smthg im forgetting to do?
a directional light has no falloff
a spotlight has a finite range, and also gets darker as you get further away
Yeah ik but theres nothing
also, if you already have a sun light, the spotlight is probably just way too dim to matter
is this an HDRP project?
URP
also, this isn't a code question. you should ask about it in #💻┃unity-talk
anyone know about edge radius for PolygonCollider2D in Physics2D/Box2D?
my CompositeCollider2D can have a working edgeradius in Outline mode, but not Polygon mode.
and PolygonCollider2D don’t have an edgeRadius field, which I think is linked
would anyone know if there’s a way to make a polygon collider that also has a radius?
it needs to be solid in interior
i guess my plan is to just make two colliders for every tilemap… lol
Is there a simple way to get line numbers to show in logs for a release build?
you can make your build in Debug mode, so it can show debug logs
But I want to build in release, because debug build has additional overhead.
idk then. sry
plus I'm seeing different behavior in release that is not happening in development build
are you doing any real code in Debug.Assert?
I remember once noticing that I had a Debug.Assert with a .TryGetValue or TryGetComponent, and then I used the value. Which blew up in my face
the whole line gets removed
I don't believe so, but thanks for that heads up. I can search the code for that
keep an eye out for any Debug.Assert with any methods with an “out” or “ref” parameter
that’s bad juju
Ah for builds of course
that is what I noticed
As the name suggest, Debug.Assert is for debugging