#Child Transform
1 messages · Page 1 of 1 (latest)
alright
essentially i have a spot light which is a child of a cube
and i want to make it so that you can only activate it while holding it
yep
First, share the script in a pastebin link.
https://gdl.space
Yes, very good.
alright
i want to make it so that you can only activate it while holding it
Can you explain a bit more?
so essentially
this is my flashlight code
right now, even if you aren't holding the cube which has the spot light as the child, you can press f anywhere on the map and it would activate and de-activate
so what i want to do is make it so that you can only activate the flashlight if you are holding it
Ah, I see.
There could be a couple of ways to go about that.
Let me read a bit.
alright
Are you familiar with referencing between scripts?
as in using instances? or like going public [var] script;
I wouldn't necessarily call it using instances. Maybe that's a term for it, idk.
But essentially yes, accessing the properties and methods of another script.
yeah, a little bit
[SerializedField] private and public do the same thing btw, but public is accessible from other scripts.
ah okay
actually, using a static might not be such a bad idea, if the logic allows for it
alright
i was originally planning to do tag
i was gonna see if the child of the cube has the tag 'flashlight'
and if it does you can pick it up
i havent actually made it yet
in your Flashlight script you can make a public static bool equipped;
And in your Pickup script, if the tag is the flashlight, make that bool true, etc.
yeah
I think that's a good solution, because the flashlight script doesn't have to ask anything for permission, it just knows.
i get you
Anyway, I'm gonna make you a simplified version of your flashlight script, for the sake of more fluent code.
you could do
mybool = !mybool;
what does that mean?
! means not
ah okay
ah okay
hold on a sec fort whatever reason this is bugging
wait nevermind im being silly
alright yeah
public GameObject flashlight;
private bool active;
void Start()
{
active = false;
flashlight.SetActive(false);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
active = !active;
flashlight.SetActive(!flashlight.activeSelf);
}
}
I believe that will behave the same as your current code.
Google: unity activeSelf
The docs description is usually more clear than memory serves 😄
ah okay
It explains the difference between other similar properties
such as activeInHierarchy
in this solution, it is kind of redundant to use it, because you already have a bool you can use, if the SetActive runs before you change the active bool
but I think it's great to have it there since it's a nice reminder
and you can change things more freely
ah okay understood
Oh right, and now for the if-statement
are you able to figure out how to finish the solution to only enable/disable when holding the flashlight?
What have you changed since you linked the scripts?
i didnt really know where to start
That's fine. Step by step.
i havent changed anything yet, however i had the idea to check the hit.transform.tag
hit is a raycast
What you want do is, when you have successfully picked up an item, to check if its tag matches the flashlight.
To make a dynamic solution for this, you can store the tag in the Flashlight script, during Awake().
And cache that in the Pickup script, to check if the tags match.
If they match, flip the bool in the Flashlight script.
And if you also drop the flashlight, it needs to be set back to false
Will you be doing this type of thing for multiple types of items, or just the flashlight?
for now just the flashlight - ill add more items in tbe future
Okay. You'll need a slightly more dynamic system for that. I can't think of something from the top off my head right now. Haven't made such a thing.
But I can help you with this.
Should probably try to get up tempo. I reckon you don't have all day.
But I need you to try to understand this first, so I don't just hand you a solution without effort.
i understand, so essentially
you store the flashlight tag in a variable
in the pickup script you check if the child tag of the cube is the flashlight tag using the variable (i think?)
if it is then equipped = true
and in the pickup script once you drop it equipped = false
i think?
let me know if im wrong
Yes, precisely.
You have the right idea.
Storing it in a variable from getting it directly from the editor, means you don't have to hardcode the tag, you can just change it in the inspector.
I got stuck in coding 😅
i mean i have this
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlashlightOnOff : MonoBehaviour
{
public GameObject flashlight;
public bool active;
public static bool equipped;
void Awake()
{
}
void Start()
{
active = false;
flashlight.SetActive(false);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
active = !active;
flashlight.SetActive(!flashlight.activeSelf);
}
}
}
and its working
Good stuff
Due to tag already existing from MonoBehaviour
I suggest changing the convention for equipped, to identify that they are your properties
public static bool _Equipped;
public static string _Tag;
And so, in the Pickup script:
private string flashlightTag; //or whatever name makes sense
private bool flashlightEquipped;
//...
private void CheckFlashLight(string foundTag) // foundTag is symbolic; you use the raycast hit
{
if(flashlightTag == foundTag)
{
FlashlightOnOff._Equipped = true;
flashlightEquipped = true;
}
}
// And in Drop() you need to do the opposite, if flashlightEquipped is true
instead of foundTag would i use hit.raycast.tag?
yes
The only thing I'm not showing in that, is where to place it in the Pickup code, but I reckon you have that covered.
If not, just ask.
would i put it at the top?
Ah, the script I'm looking at is using hit.transform.tag == "item"
have you changed this approach?
Post the pickup script again
in Pickup1 thats what i used
void Pickup1()
{
RaycastHit hit;
if (Physics.Raycast(camera.transform.position, camera.transform.forward, out hit, maxPickupDistance))
{
if (hit.transform.tag == "Item")
{
if (isHolding) Drop1();
itemCurrentlyholding = hit.transform.gameObject;
foreach (var c in hit.transform.GetComponentsInChildren<Collider>()) if (c != null) c.enabled = false;
foreach (var r in hit.transform.GetComponentsInChildren<Rigidbody>()) if (r != null) r.isKinematic = true;
itemCurrentlyholding.transform.parent = transform;
itemCurrentlyholding.transform.localPosition = Vector3.zero;
itemCurrentlyholding.transform.localEulerAngles = Vector3.zero;
isHolding = true;
}
}
}
thats what i used
I have an idea
instead of using tag == "item" to identify items
you can place all the pickupable items in a specific layer
and in the Raycast, only check that Layer
then the raycast.hit will always be null if you don't hit one.
Just mind the distance, or you might pick up an item two floors down :))
could you please put it in an example? im a bit confused 😅
Raycast has multiple declarations.
As I'm reading the docs, they all have LayerMask with default values if not specified
Have you worked with Layers before?
Do you know how they work?
i have not
Alright. Select the flashlight game object.
Notice the Layer drop down at the top in the inspector.
Create a new layer called Pickups
Then change its layer to that.
like this?
Yes 👍
sec, I'm rusty on Raycast
alrighty
I've always used this, but it's not the most flexible approach.
LayerMask.NameToLayer("Pickups");
Cache it during awake, to improve performance.
NameToLayer() returns the integer that represents that layer
ah okay
Raycast has an overload for it
where should i put this?
might have to rearrange the order of your Raycast parameters
Do you have a configured IDE?
i have vsc
when you type this. do you get autocomplete-suggestions?
inside some void
typing this and . should give you suggestions for what is known that is there
if not, you'll need to go through the #854851968446365696 Configure IDE section for VSC
typing . doesnt do anything
then it's time to actually have things start making sense when coding
alright
go do the thing. Most people don't need help. Just read and complete every step, for Visual Studio Code (if that's what you're using)
alright
I strongly recommend Visual Studio Community for beginners.
It is objectively better, and you have less potential issues as a beginner.
Though, if your hardware is not powerful, I suppose VSC might be more practical to use.
eh, im somewhat well versed in py ive just never done c# before
alright, so you're at least familiar with VSC, that's good then
do i need intellisense?
what else should i install
Just follow the Configure IDE guide and let me know when intellisense works etc.
private int _layerPickups;
private float _rayMaxDistance;
private void Awake()
{
_rayMaxDistance = 100f;
_layerPickups = LayerMask.NameToLayer("Pickups");
}
private void Update()
{
Vector3 origin = transform.position;
Vector3 direction = transform.forward;
if (Input.GetKeyDown(KeyCode.Q))
{
if (Physics.Raycast(origin, direction, out RaycastHit hit, _rayMaxDistance, _layerPickups))
{
// Highly performant Raycast, because it only checks one Layer.
// To polish this feature, you will have to use a LayerMask that includes Ground, Walls and Obstacles.
// (Unless you want your character to have... special powers)
// CodeMonkey video: https://www.youtube.com/watch?v=uDYE3RFMNzk
}
}
}
i have the uh c# extension
does it work?
no, i have no idea why
Did you read every single step?
might just need to restart Unity and VSC
but I don't think it's necessary
(UnityEditor) Preferences > External Tools
make sure it's the default
Hmm
should i just continue? or
It seems the VSCode extension for Unity should work, but is full of bugs and becoming deprecated
oh okay
Might want to use Community until you get a good grasp on things.
Anyway
There are like 16 different declarations for Raycast
yep
you can surf them with intellisense
right
The code I linked above works with out hit and layer
notice how I defined the out
it declares the variable hit inside the Raycast declaration
by writing the type name
adjust distance ofc
or just make it infinite
float.maxValue or something
this goes in the flashlight file?
ah right
It could arguably be written in a better way (the entire solution), but you will figure that out once you start improving the pickup script system
Ideally, Flashlight controls itself, but since you need to know when to deactivate it via Drop, this is the most direct way
if (Physics.Raycast(origin, direction, out RaycastHit hit, _rayMaxDistance, _layerPickups))
what should i put in this if?
I think you misunderstand.
It is an example of how your Raycast should be changed, to include Layer
oh
the parameters must be passed in that order
it would be more apparent to you, if you had intellisense, which is actually required in order to get help in these channels.
I can bare with it for a short while, depending on how difficult this is for you.
Intellisense should work for VSCode, if you followed all the steps in the guide.
But VSCommunity has full support and less bugs, if any at all, and will make it easier for people to relate and help you.
are you talking about this?
I can't be certain, it should be apparent in the guide.
I haven't used VSCode for 2 years
wait a second
i think i might just have tab complete disabled
i just turned this on
windows
hm - not working
im not sure tbhh
how would i use _layerPickups in this situation
That is explained in the example
private int _layerPickups;
private float _rayMaxDistance;
private void Awake()
{
_rayMaxDistance = 100f;
_layerPickups = LayerMask.NameToLayer("Pickups");
}
private void Update()
{
Vector3 origin = transform.position;
Vector3 direction = transform.forward;
if (Input.GetKeyDown(KeyCode.Q))
{
if (Physics.Raycast(origin, direction, out RaycastHit hit, _rayMaxDistance, _layerPickups))
{
// Highly performant Raycast, because it only checks one Layer.
// To polish this feature, you will have to use a LayerMask that includes Ground, Walls and Obstacles.
// (Unless you want your character to have... special powers)
// CodeMonkey video: https://www.youtube.com/watch?v=uDYE3RFMNzk
}
}
}
yeah i saw, is the syntax in the docs?
Yes, it's the second declaration in https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
Or, not all 16 of them are there, but that's the one that matches the most.
I asked around and have been confirmed that the VSCode extension still works to some extent.
If you have not made it work yet, then I suspect it can only be that you have disregarded one or more of the points in the guide.
I don't know what you mean by that.
Proper Unity integration provides intellisense, and proper error messages.
Intellisense doesn't just provide knowledge of which properties and functions exist, but also helps read how they work.
Which step in the guide is that?
just to be sure sure we're looking in IDE configuration
Step 1. Did you install the SDK?
yep i already have it
and since it was installed, Windows has been restarted?
yup
not shut down / powered up
yep
And step 3. You installed the C# extension
yep i ahve that
uncheck
yeah i unchecked it
This has been going way too slow btw.
Thought I could take you through the whole thing, but I really need to go now.
Make sure you do all the steps
but also, here was the latest feedback:
It was nonfunctional for a week after installing it on my current setup, despite trying absolutely everything
After that it just started working with no change on my part
That happened on both Windows 10 and 11
Good luck o/