#no object with the proper layerMask to
1 messages · Page 1 of 1 (latest)
If the phantom walls don't get highlighted when you click the log entry, then the game object is gone
the coords for that hit are on the blue circle
I know that's how that works which is why I'm so confused
How do you add a wall to a room frame?
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
/* Script Purpose
* Highlight where mouse is pointing with a red frame
*/
public class RedFrame : MonoBehaviour
{
[SerializeField] GameObject outline;
private GameObject currentFrame;
[SerializeField] BoxCollider boxScale;//scales frame to match that of hitbox
[SerializeField] private LayerMask theLayerMask;
private void Update()
{
theLayerMask = AddCube.SetFinalMask(PlaceSelect.PlaceMode());
Destroy(currentFrame);
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//where user hovers mouse over
bool cast = Physics.Raycast(ray, out RaycastHit hit, 500f, theLayerMask);
if (cast && hit.transform.gameObject.CompareTag("Room"))//if user hovers mouse over a room
{
Vector3 v = 90f * hit.normal;
Vector3 normals = Quaternion.AngleAxis(90, Vector3.up) * v;//rotates object to face outwards
currentFrame = Instantiate(outline, hit.transform.position + VectorMult(hit.normal, boxScale.size) * 0.5f, Quaternion.Euler(normals));//generates new outline
}else if (cast && hit.transform.gameObject.CompareTag("FakeWall"))
{
currentFrame = Instantiate(outline, hit.transform.position, Quaternion.Euler(-90f, hit.transform.eulerAngles.y, hit.transform.eulerAngles.z));
}
}
private Vector3 VectorMult(Vector3 firstVector, Vector3 secondVector)//outputs (x1*x2, y1*y2, z1*z2), basically a half dot product
{
return new Vector3(firstVector.x * secondVector.x, firstVector.y * secondVector.y, firstVector.z * secondVector.z);
//blender objects have Z up, unity has Y up. Swapped the two. Unswap if for unity objects or importing meshes from a Y up software
}
}```
this is the only destructive code
and it destroys the red frame that highlights where the mouse is pointing
void WallSelect(RaycastHit hit, GameObject Wall)
{
GameObject newWall = Instantiate(Wall, hit.transform.position, Quaternion.Euler(new Vector3(0,hit.transform.eulerAngles.y,0)), hit.transform);
/* NOTE:
* sometimes, this ray points down. I don't know why but it does not produce any issues yet. In the future, it might, so I have left this debug function in here for you
* Debug.DrawRay(hit.transform.position, hit.transform.rotation * new Vector3(0, -1f, 0f), color:Color.green, 5f);
* */
if (Physics.Raycast(hit.transform.position, hit.transform.rotation * new Vector3(0, -1f, 0f), out RaycastHit hitInfo, 0.5f, wallMask))
{
Instantiate(newWall, hitInfo.transform.position, Quaternion.Euler(new Vector3(0, hitInfo.transform.eulerAngles.y, 0)), hitInfo.transform);
}
}```
this is the code to add a new wall
void Update()
{
PlaceSelect.Mode mode = PlaceSelect.PlaceMode();
finalMask = SetFinalMask(mode);
if (Input.GetMouseButtonDown(0))//if user clicks
{ //raycasts passing through blender objects for some reason
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//where user clicks
bool cast = Physics.Raycast(ray, out RaycastHit hit, 500f, finalMask);
if (cast && !hit.transform.gameObject.CompareTag("Untagged"))//if user clicks an object, make something
{
switch (mode)
{
case PlaceSelect.Mode.Room:
RoomSelect(hit);
break;
case PlaceSelect.Mode.Wall:
KillChildren(hit.transform.gameObject);
WallSelect(hit, onlyWall);
break;
}
}
}
}```
and the Update() method where it is called in
finalMask in this case is set to wallMask because you have to be in wall select mode to add a wall and entering that mode sets finalMask to wallMask
can you share the entire script in a single pastebin?
that will make it easier to read
btw, Vector3.Scale already exists; you don't need vectorMult
I realized that
this is one of the older scripts I have written but has been recently modified with WallSelect
also vectorMult swaps y and z becauase blender models
you can test this theory by adding an OnDestroy method to something on the EZWall
void OnDestroy() {
Debug.Log("Destroying: " + gameObject.GetInstanceID());
}
and also log hit.transform.gameObject.GetInstanceID() when you hit something in the FindNeighbors method
is there a prebuilt function to detect when something is destroyed?
like where do I call that function
it's a message, like Update
put it on any component that's on the same object as the wall's collider
oh the function is autocalled
do I have to put it into a script I have or into WallEZ
i don't know what you mean by "into WallEZ"
put it into the script for any component that's attached to the same game object as the wall's collider
if no such component exists, make one
so just add this script as a component to WallEZHolder?
Add it to whatever object has the collider
also, I noticed that you instantiate Wall to get newWall, then instantiate newWall again
wait where?
WallSelect, lines 75 through 83
oh yeah
newWall is left parented to hit.transform
yeah that's a good point
the other wall is stuck onto whatever you hit in the raycast in that method
I don't really understand what's happening there
testing without newWall and changing 2nd instantiation to just Wall
for some reason no wall is generated
oh yeah
so basically, it adds a wall to where you click. Then, if it detects a room on the other side, it adds a wall
this ensures you don't have a one sided wall
so if I click here
nvm forgot to save
I should document that
adds a wall to both sides
yeah not commenting that was a crime
you can turn on "Apply Transforms" in Blender so that the model doesn't need any rotating in unity
and yeah I wrote that rotation code before I knew what Quaternion.AngleAxis was
(this causes problems if you have objects parented to each other in blender, though)
well, moreso, it seems weird that you'd be rotating a down-vector to get a vector that doesn't point down!
I presume your ray points down any time whatever you hit happens to not have that 90-degree X axis rotation you get by default
You know, one thing that comes to mind here
yeah?
RoomSelect calls KillChildren on the newly spawned room
oh hang on
yeah
GameObject newObj = Instantiate(hit.transform.gameObject, hit.transform.position + vectorMult(hit.normal, boxScale.size), hit.transform.rotation);
I MISSED THAT
You're cloning the room
The walls are destroyed, but destruction happens at the end of the frame.
The walls are still there.
So you hit them with your raycasts
Then the walls die at the end of the frame.
That's your issue.
well, you do
well, you do it after calling Instantiate
then, in Start, the room does the raycasts
actually, that should be on the next frame...
yeah delay it a frame
because all destruction is at the end of the frame
a detail I forgot when writing that code
but i'd expect Start to have already done that for you
You can try making KillChildren deactivate the objects too
I need to scram in a few minutes btw
same lol
but that's my best hunch right now
It just doesn't square up with the raycasts happening in Start on the next frame
Start already doesn't run until the start of the next frame
so neither does KillChildren
because it is called in start
so I need to do it the frame after start is called
oh yeah mb
Ah, but you're looking at its usage with WallSelect
anyway, try deactivating the objects and then destroying them
newObj.transform.GetChild(i).gameObject.SetActive(false);
it worked!
I'd have to squint at this harder to see why it worked. It feels like it shouldn't have
seriously thank you so much
but you're welcome anyway (:
Imma just blackbox it for now
I've gotten bitten by delayed destruction a few times
this bug has been beating me up for months