Afternoon, Recently while trying to develop the more; Err Graphical part of my 'Editor Extension', Through towards unity3d's Audience I've been looking at creating more of a dynamic window for screen sizes!
Throughout my testing I've noticed many hard-core glitches that I cannot seem to persuade, Currently I've tried "doubles, int, float, etc.. etc..", Though my issue might just be with unity, I'm sure someone here has had this event occur while attempting to scale their "Editor Application", Here are some visual representations of the variable issues i've been having.
Error && Success Image Collection!
Upon my Journey of Dynamic Screen Fitting Here is some of my current attempted code that I have within my project for the window as of now.
private Rect Topic_Selection_Rect_Window = new Rect(5, 5, Screen.width / 6, 350);
static void Init()
{
EditorWindow Toolbox = GetWindowWithRect(typeof(Toolbox), new Rect(0, 0, 1250, 900));
Toolbox.Show();
}
private void OnGUI()
{
BeginWindows();
GUILayout.Window(0, Topic_Selection_Rect_Window, Topic, "Please Select A Listed Topic!");
EndWindows();
}
private void Topic(int id)
{
GUILayout.TextField("pre-text");
}
Now with the code shown above, We Have on the "Price rect topic_selection_rect_window", We have the idea that 'Oh, we can just use the API for 'Screen.width', Though initially i've noticed that the idea of that is knowing the users screen - information, Though the reality of it is I'm thinking that initally it's all wonky for inital load to get user-information which I need to entail an idea on how to attempt to get that upon init, Though i've tried hasn't seemed to work accordingly, Though once I load and it's all wonky and I exit and load again it's less wonky and one last time and it's fine; I've had some issues for some time such as "Screen.height" never seems to work and give me a good ## or Screen %% availability and just tends to not work with my monitor or what; I'm fairly new to programming and I'm looking to figure out how this API works, etc thanks for any
comments / answers!
-- DrEncompass --
After-Hours of tinkering, I'd have given up while messing around I later had an issue with my window not being able to have de-bugging and I had to re-boot Unity3d Every-time I had crashed my Editor-Window, So after some messing around I figured I could just directly call the window with the [.show();], And so far it's appearing to be a strong solution!
Related
Getting the notch size isn't supported in Unity.
I've tried to first get the notch size for all iOS devices in Xcode and then convert them to pixels in Unity but it’s always wrong and I’m not sure why.
No information regarding this can be found on the internet - I think this is because no games require knowing the exact notch size for every iOS device especially in Unity but in my case, I do need it so I can do something with it.
It would be nice to be able to get the position as well (notch and 14 Pro's island)
I know how to handle safe area in Unity. This is not about that. This is about getting the notch size.
Since hardcoding seems to be the only option at this point, I convert these values to px because Xcode uses pt and Unity uses px. However things become too small in Unity when I do that.
var size: CGSize {
switch self {
case .large:
if UIDevice.current.hasSmallNotchArea {
return .init(width: 206.30, height: 29.10)
} else {
return .init(width: 207.50, height: 31.30)
}
case .medium:
return .init(width: 160.90, height: 33.20)
case .pill:
return .init(width: 124, height: 35.20)
}
}
It doesn't seem like Unity has any support for giving you that info, so your best bet will likely be to make your own solution by getting the "DeviceGeneration", figuring out if you're on one with the notch and then having a catalogue of the different notch sizes and positions to return.
Probably not what you wanted to hear, but unless someone has put it up as a github repo I couldn't track down, I think you might have to forge the way on this one.
Also instead of using pixels, would likely be more reliable to use percentages and space from the edges to generate it on the fly.
The problem:
I've been working on trying to create a 3D position in Worldspace based on a 2D face RGB face detection, similar to this Microsoft example. I am using Unity 2020.3.16f1, MRTK 2.8.2 and C# for the Unity scripts. I have been able to convert the C++ code shown in the link to C# with a lot of success. One final issue is accessing the HoloLens 2 origin SpatialCoordinateSystem to be used in the Transform between the camera's 2D coordinate system and the 3D worldspace system.
The SO question at this link asks a very similar question, and I have tried to use SpatialLocator.GetDefault().CreateStationaryFrameOfReferenceAtCurrentLocation().CoordinateSystem() as the answers suggest. I call this function in Unity's "Awake" method, to ensure it is set as early as possible, as shown below.
private void Awake()
{
worldSpatialCoordinateSystem = SpatialLocator.GetDefault().CreateStationaryFrameOfReferenceAtCurrentLocation().CoordinateSystem;
}
Problem is that, if the user's headset is moving while the application starts, I notice an offset in the 3D locations commensurate with the direction/position of the head when the application was starting. I have narrowed the problem down to the fact that the HL2 and Unity set an origin SpatialCoordinateSystem just before the function in Awake is called, accounting for the offset between what I expect and what I see.
What I've tried:
I have tried using some of the other solutions listed here as well. I cannot use UnityEngine.Windows.WebCam.PhotoCapture becuase of the way I am create still image captures, and (SpatialCoordinateSystem)Marshal.GetObjectForIUnknown(WorldManager.GetNativeISpatialCoordinateSystemPtr()) appears to be deprecated and unusable. Finally, I tried CreateStationaryFrameOfReferenceAtCurrentLocation(Vector3, Quaternion), and used the inverse of the current Camera.main position and rotation, hoping to compensate for the offset, but it did not appear to work (NumericsConversionExtensions is the UnityEngine-to-System.Numerics converver found here). That code is below.
worldSpatialCoordinateSystem = SpatialLocator.GetDefault().CreateStationaryFrameOfReferenceAtCurrentLocation(NumericsConversionExtensions.ToSystem(Camera.main.transform.position*-1),
NumericsConversionExtensions.ToSystem(Quaternion.Inverse(Camera.main.transform.rotation))).CoordinateSystem;
My question:
Is there either another way to access the origin spatial coordinates or possibly to compensate for the offset when the user is moving their head before Awake is called?
I spent 3 days working on the solution, and found one 1 hour after asking SO. For those who come here, use the code below, originally found here.
using Microsoft.MixedReality.OpenXR;
worldSpatialCoordinateSystem = PerceptionInterop.GetSceneCoordinateSystem(Pose.identity) as SpatialCoordinateSystem;
I'm using the FadeObjectInOut script from the wiki (http://wiki.unity3d.com/index.php/FadeObjectInOut)
It's attached to two different objects (each), which trigger indiviudally. It'll resolve in
IndexOutOfRangeException: Array index is out of range.
FadeObjectIO.SetNewColor (UnityEngine.Renderer[] rendererObjects, Int32 i) (at Assets/Scripts/FadeObjectIO.cs:132)
It reffers to the line
Color newColor = (colors != null ? colors[i] : rendererObjects[i].material.color);
..., which tried to export as an function and still calls the same error. The whole code snippet relies on IEnumerator.
Due to the fact, that this only happens every now and then, I'm totally confused. I can't provoke it by triggering the events at the same time, I can't provok it by flashing between fadeOut and unIn super fast.
As solution, I tried things from the internet and also the "How to Avoid" of this question: What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
The last time, I triggered my oculus trigger on/off in high frequency and nothing happend. Frustrated I wanted to take the headset off and as I put down my controllers, it crashed again. (It's on the Touch trigger and thereby easily fast triggerable.)
I can't help myself anymore...
Thanks for any advise
.
EDIT: below the thrown error + the debug code. After fading out, the Renderers are getting enabled=false.
Since we are in a while loop, it doesnt really make sense to me tho, that the dot might've been already faded out (and it's renderer therby deactivated) being an error for the array - because it doesnt get any changes. Hmmmm.
Debug everything
Edit: new state
im sorry if im writing in weird ways. pretty new to programming, going the first year so I figured i could use some help..
im trying to get an "End screen" in my group and i have no idea really how to do it.
we have three levels and after the third and last level a screen should pop up like, "Do you want to play again/Exit?"
here's to my problem, how do I begin with just simply starting? I have tried myself and created a SpriteFont named "EndScreen" under Objects.
now later down in "draw(GameTime)" i did this:
" // Draws the Ending screen of game
switch (CurrentGameState)
{
case Gamestate.EndScreen:
{
spriteBatch.Draw(Content.Load<Texture2D>("Sprites/Endscreen"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
btnPlay.Draw(spriteBatch);
break; "
now i get the error: "unreachable code detected"
I would really appreciate If you could give me some step through step.
sorry if it looks bad and some type errors, I live in sweden and new to programming and this site! I also wonder if i did the coding right and putting the code on the right places, im very insecure about programming
you have an extra " after the break
Since break will jump out of the switch statement, the code path will never be able to reach this part of the code. Simply removing will fix this
void Update(GameTime g)
{
CurrentGameState = GameState.EndScreen;
}
I'm not going to give you the answer to the question you asked (#sayse already did that perfectly fine), but rather the question your code asked.
When you're drawing out your image you call the following code:
spriteBatch.Draw(Content.Load<Texture2D>("Sprites/Endscreen"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
This means every frame that your game draws that image to the screen it is attempting to load in a new instance of the texture at "Sprites/Endscreen." While XNA is able to realize not to load it, the process of checking if it already has been loaded is somewhat slow. You may not notce it immediately, but if you get enough images on a screen drawing like that you'll notice significant "lag" or drops in framerate.
A good solution to this problem would be to make a field (class member variable) at the top of your class that this code is being called in. Make it a Texture2D and call it something relevant like endScreen. Then in LoadContent load the texture into your endScreen object. Lastly changed your call to spriteBatch.Draw() to use that Texture2D. Below I have included an example of what you might want to do.
//Fields
Texture2D endScreen;
//Load Content
endScreen = Content.Load<Texture2D>("Sprites/Endscreen");
//All Your Class Code
//Draw
spriteBatch.Draw(endScreen, new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
I'm working on some kind of mod for Terraria (written in C# and using XNA), in which I need to use some blend modes. I didn't have any troubles getting additive blending to work, but subtractive one causes me some problems.
I managed to display stuff with subtractive blending, but it doesn't really want to return to the standard mode. SpriteBatch.End and Begin doesn't help at all.
This is my custom BlendState:
public readonly static BlendState
bsSubtract = new BlendState{
ColorSourceBlend = Blend.SourceAlpha,
ColorDestinationBlend = Blend.One,
ColorBlendFunction = BlendFunction.ReverseSubtract,
AlphaSourceBlend = Blend.SourceAlpha,
AlphaDestinationBlend = Blend.One,
AlphaBlendFunction = BlendFunction.ReverseSubtract
},
Drawing code:
sb.End();
sb.Begin(SpriteSortMode.Immediate,bsSubtract);
(...drawing drawing blah...)
sb.End();
sb.Begin(SpriteSortMode.Immediate,BlendState.Additive);
The problem is, everything that is drawn after this code seems to still use some old options (half-transparent, bland). What am I doing wrong?
I even tried calling just sb.End() and sb.Begin() before setting the blend state back, or using another custom blend state which was a standard additive one, just with BlendFunctions set to Add, to no avail.
EDIT: Seems like setting ANY custom BlendState makes it do that...
EDIT2: Seems like the problem was me splitting the drawing to 3 separate places: one for item slots, one for tiles and one for world in general. And in one of these (items) I forgot to set the SpriteBatch before using and reset it afterwards. I should have spent more time looking at my code. Still, thanks for trying to help!
(can't close the question just yet, gonna close it after StackOverflow lets me do it)
The default blending mode is BlendState.AlphaBlend.
Try replacing BlendState.Additive with BlendState.AlphaBlend in your code. Or possibly NonPremultiplied, depending on what Terraria is actually using.
Better yet, you could read out exactly the blend state that Terraria was using, as SpriteBatch sets it on the graphics card and simply leaves it there. Here is some untested code that should do exactly that:
sb.End(); // Sets blend state
BlendState previousState = GraphicsDevice.BlendState; // Retrieve it
sb.Begin(SpriteSortMode.Immediate, bsSubtract);
// (...drawing drawing blah...)
sb.End();
sb.Begin(SpriteSortMode.Immediate, previousState); // Re-use it
Seems like the problem was me splitting the drawing to 3 separate places: one for item slots, one for tiles and one for world in general. And in one of these (items) I forgot to set the SpriteBatch before using and reset it afterwards. I should have spent more time looking at my code. Still, thanks for trying to help!