Name of this selectable scroll in unity editor? - unity3d

As you can see in the picture, "Layout0" is selected with dark blue color.
I want to make this box too in my custom editor, but what I actually found is that this is not EditorGUILayout.BeginScrollView and other whatever stuffs.
could someone please tell me the keyword of this selectable box?

I am not entirely sure how the highlighting works but here's how I think it's implemented.
Make a scrollable view using GUILayout.BeginScrollView
Make a vertical view, but with help box style GUILayout.BeginVertical(EditorStyles.helpBox)
For the highlighting, create a blue texture and assign it to a GUIStyle, which you then use for the button. Do this on Awake so you only do this once.
Texture2D texture = new Texture2D(1, 1);
for(int x = 0; x < 1; x++)
{
for(int y = 0; y < 1; y++)
{
texture.SetPixel(x, y, Color.blue);
}
}
texture.Apply();
this.selectedStyle = new GUIStyle();
this.selectedStyle.normal.textColor = Color.white;
this.selectedStyle.normal.background = texture;
Change the buttons to label buttons GUILayout.Button("name", currentSelected ? this.selectedStyle : GUIStyle.label)

Related

How to know coloring is complete on the sprite?

I am trying to make color game in that there are three object border, 3d cube, and a pointer(tube), here i'm painting a 3d cube with a pointer by changing its texture and put a sprite on the cube so i want to detect the condition while i almost complete the coloring inside the sprite border how can i do that in unity?
Like in this image
I want to know how to detect almost complete coloring within the boundry sprite.
To detect if the coloring inside the sprite border is almost complete, you can use a combination of Unity's built-in collision detection and image processing techniques. Something like this:
First create a sprite mask on the sprite border to mask the cube image. This will allow you to apply an effect to only the area inside the border.
Then sample the color of each pixel inside the border using the GetPixels method of the Texture2D class. Store these values in an array.
Calculate the average color of all the pixels in the array.
Compare the average color to a pre-defined threshold color to determine if the coloring is complete. If the average color is close enough to the threshold color, you can assume that the coloring is complete.
Repeat steps 2-4 in a loop while the player is painting the cube to continuously check if the coloring is complete.
Once the coloring is complete, you can trigger an event or perform some other action in your game.
using UnityEngine;
public class ColorDetection : MonoBehaviour
{
public SpriteRenderer spriteRenderer;
public Texture2D maskTexture;
public Color thresholdColor;
private void Update()
{
Color averageColor = GetAverageColor();
if (IsColorSimilar(averageColor, thresholdColor))
{
Debug.Log("Coloring is complete");
}
}
private Color GetAverageColor()
{
Texture2D texture = spriteRenderer.sprite.texture;
Rect spriteRect = spriteRenderer.sprite.rect;
Color[] maskPixels = maskTexture.GetPixels();
Color[] spritePixels = texture.GetPixels((int)spriteRect.x, (int)spriteRect.y, (int)spriteRect.width, (int)spriteRect.height);
int count = 0;
Color sum = Color.clear;
for (int i = 0; i < maskPixels.Length; i++)
{
if (maskPixels[i].a > 0)
{
count++;
sum += spritePixels[i];
}
}
return sum / count;
}
private bool IsColorSimilar(Color a, Color b)
{
float delta = 0.05f;
return Mathf.Abs(a.r - b.r) < delta && Mathf.Abs(a.g - b.g) < delta && Mathf.Abs(a.b - b.b) < delta;
}
}

Changing the color of a gameobject shows as white not the colour requested

I have a set of gameobjects (simple cubes). I can set their initial colour when instantiating them. However when I try and change the colour by code, the object in the game view and inspector show as white, but in the colour picker show the correct colour!
There is a single directional light (the default one).
IEnumerator ColourChange()
{
Color targetColour = new Color(Random.Range(0, 255), Random.Range(0, 255), Random.Range(0, 255));
Debug.Log("color = " + targetColour);
for (int x = 0; x < CreateCubeGrid.GRIDSIZE; x++) {
for (int z = 0; z < CreateCubeGrid.GRIDSIZE; z++) {
CreateCubeGrid.cubeGrid[x,z].GetComponent<Renderer>().material.color = targetColour;
}
yield return new WaitForSeconds (0.05f);
}
}
Colours are 0 to 1 not 0 to 255.
Use Color32 if you want to use 0-255 values.
Color32 Documentation
In order to change the material's color, you must tell it exactly what color you're trying to change, by using Shader.Find("_YourColor") (Emission, Albedo, etc).
An approach that should work for materials using Standard Shader can be seen below:
private void ChangeColor(Color color)
{
//Fetch the Renderer from the GameObject.
Renderer rend = GetComponent<Renderer>();
//Find and set the main Color ("_Color") of the Material to the new one
rend.material.shader = Shader.Find("_Color");
rend.material.SetColor("_Color", color);
}
You can read more about changing a Material's color at Unity's Documentation.

Visual Studio Extensibility: Rectange-s added to Children class of the ScrollbarMargin prevent mouse clicks on the scrollbar

I've developed an extension some time ago that allows to highlight a section of the scrollbar with the specified color, here is how I do it:
/// <summary>On layout changed analyze the regions and lines and highlight them on the scroll bar if needed.</summary>
private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
{
Children.Clear();
int n = AllAdornments.TextAdornment.Regions.Length;
for (int i = 0; i < n; i++)
{
if (AllAdornments.TextAdornment.Regions[i].Adornment != null
&& AllAdornments.TextAdornment.Regions[i].EndLine < e.NewSnapshot.LineCount)
{
var rect = new Rectangle();
var firstLine = e.NewSnapshot.GetLineFromLineNumber(AllAdornments.TextAdornment.Regions[i].StartLine);
var lastLine = e.NewSnapshot.GetLineFromLineNumber(AllAdornments.TextAdornment.Regions[i].EndLine);
double top, bottom;
double firstLineTop;
MapLineToPixels(firstLine, out firstLineTop, out bottom);
SetTop(rect, firstLineTop);
SetLeft(rect, ScrollBarLeftPadding);
MapLineToPixels(lastLine, out top, out bottom);
rect.Height = bottom - firstLineTop;
rect.Width = ScrollBarWidth;
Color color = Communicator.LerpColor(AllAdornments.TextAdornment.UserBackgroundCol,
AllAdornments.TextAdornment.Regions[i].Adornment.Color, ScrollBarIntensity
* AllAdornments.TextAdornment.Regions[i].Adornment.IntensityMult);
color.A = ScrollBarOpacity;
rect.Fill = new SolidColorBrush(color);
Children.Add(rect);
}
}
}
Here is how it looks in Visual Studio:
This worked perfectly for a long time (around 1,5 - 2 years), but when I updated VS four months ago a problem emerged: I can no longer click on the section of the scrollbar margin with the colored Rectangle - the mouse click simply does nothing as long as it is above the colored Rectangle. On the empty section of the scrollbar it works as usual. Before I could not only click on my Rectangle-s, but hold the mouse button down and drag the scrollbar. Is there any way I can bring back this functionality?
Can you try setting rect.IsHitTestVisible = false;

cocos2dx: Sprite3D rotating, culling error

Hi I'm trying to have 2 sprites with different z in 3d world and a camera that rotates around the center of the screen and points at the center of the screen.
Even if the sprites has different z (and zorder, I don't know if this is necessary) the sprites are always visualized while I'm expecting to have the second sprite hided from the other...
This is helloworld layer init
auto sp3d = Sprite3D::create();
sp3d->setPosition(visibleSize.width/2, visibleSize.height/2);
addChild(sp3d);
auto sprite = Sprite::create("JP9_table.png");
auto spritePos = Vec3(0,0,0);
sprite->setScale(0.3);
sprite->setPosition3D(spritePos);
sp3d->addChild(sprite,0);
auto sprite2 = Sprite::create("JP9_logo_yc.png");
auto spritePos2 = Vec3(0,0,10);
sprite2->setPosition3D(spritePos2);
sp3d->addChild(sprite2,10);
sp3d->setCullFace(GL_BACK);
sp3d->setCullFaceEnabled(true);
this->setCameraMask((unsigned short)CameraFlag::USER2, true);
camera = Camera::createPerspective(60, (float)visibleSize.width/visibleSize.height, 1.0, 1000);
camera->setCameraFlag(CameraFlag::USER2);
camera->setPosition3D(spritePos + Vec3(-200,0,800));
camera->lookAt(spritePos, Vec3(0.0,1.0,0.0));
this->addChild(camera);
this->scheduleUpdate();
angle=0;
and this is update:
void TestScene::update(float dt)
{
angle+=0.1;
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
Vec3 spritePos=Vec3(visibleSize.width/2,visibleSize.height/2,0);
camera->setPosition3D(Vec3(visibleSize.width/2,visibleSize.height/2,0) + Vec3(800*cos(angle),0,800*sin(angle)));
camera->lookAt(spritePos, Vec3(0.0,1.0,0.0));
}
I have tryed something simplier:
auto sp3d = Sprite3D::create();
sp3d->setPosition(visibleSize.width/2, visibleSize.height/2);
addChild(sp3d);
auto sprite = Sprite::create("JP9_table.png");
auto spritePos = Vec3(0,0,0);
sprite->setScale(0.3);
sprite->setPosition3D(spritePos);
sp3d->addChild(sprite,0);
auto sprite2 = Sprite::create("JP9_logo_yc.png");
auto spritePos2 = Vec3(0,0,10);
sprite2->setPosition3D(spritePos2);
sp3d->addChild(sprite2,10);
sp3d->setCullFace(GL_BACK);
sp3d->setCullFaceEnabled(true);
even with sp3d->runAction(RotateTo::create(20,vec3(0,3000,0))) same error.
Is it a cocos2dx bug?
the sprite with z=10 disappear before it is covered by the other sprite...
remain hidden for a while, and when it should be hidden completely reappear!!!
Do I have forgot something?
thanks
Maybe you should check this.
_camControlNode = Node::create();
_camControlNode->setNormalizedPosition(Vec2(.5,.5));
addChild(_camControlNode);
_camNode = Node::create();
_camNode->setPositionZ(Camera::getDefaultCamera()->getPosition3D().z);
_camControlNode->addChild(_camNode);
auto sp3d = Sprite3D::create();
sp3d->setPosition(s.width/2, s.height/2);
addChild(sp3d);
auto lship = Label::create();
lship->setString("Ship");
lship->setPosition(0, 20);
sp3d->addChild(lship);
and
_lis->onTouchMoved = [this](Touch* t, Event* e) {
float dx = t->getDelta().x;
Vec3 rot = _camControlNode->getRotation3D();
rot.y += dx;
_camControlNode->setRotation3D(rot);
Vec3 worldPos;
_camNode->getNodeToWorldTransform().getTranslation(&worldPos);
Camera::getDefaultCamera()->setPosition3D(worldPos);
Camera::getDefaultCamera()->lookAt(_camControlNode->getPosition3D());
};

Is there any way to make some rectangular areas of a mask to be transparent?

I am using UGUI to make a Novice guide to guide people to play my game.
And need the whole UI be mask, but some rectangular areas to be lighted.
How to do?
Create a new gameobject and add a image component to it. Create a image with transparent areas where you want your ui to be visible. Assign that image to the image component. Then add a mask component
Put your other gui elements inside this gameobject so that is could overlap and hide everything except transparent areas. Here is the picture of demo setup.
IMHO, what you want to achieve is not easy to be done perfectly in Unity. Here is my personal solution:
I put a black panel below every other GUI, so that it darkens my entire screen.
I put an empty game object called BrightRoot below the panel, so that everything under BrightRoot will float over and "brightened".
In my tutorial script, I add function to look for a UI game object by name and change its parent to the BrightRoot. In example:
// To brighten the object
GameObject button = GameObject.Find("PlayButton");
Tansform oldParent = button.transform.parent;
button.transform.SetParent(BrightRoot, true);
// To darken it again
button.transform.SetParent(oldParent, true);
The perfect solution would be to write a UI shader that darken any pixel outside some rectangles and brighten the inside. Then set that shader to all UI objects.
Editted:
This just another easy method, using UI Vertex effect. Just need to implement IsPointInsideClipRect, put this component to your UI objects, and set the rectangles list:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
[AddComponentMenu("UI/Effects/Clip")]
public class Clip : BaseVertexEffect
{
// We need list of rectangles here - can be an array of RectTransform
public RectTransform[] ClipRects;
public override void ModifyVertices(List<UIVertex> vertexList)
{
if (!IsActive())
{
return;
}
bool isClipped = true;
for (int i = 0; i < count; i++)
{
UIVertex uiVertex = vertexList[i];
foreach (RectTransform rect in ClipRects)
{
if (IsPointInsideClipRect(rect, uiVertex.position))
{
isClipped = false;
break;
}
}
}
Color32 color = isClipped ? new Color32(0.5f, 0.5f, 0.5f, 0.5f) : new Color(1.0f, 1.0f, 1.0f, 1.0f);
for (int i = 0; i < count; i++)
{
UIVertex uiVertex = vertexList[i];
uiVertex.color = color;
}
}
private static bool IsPointInsideClipRect(RectTransform rect, Vector3 position)
{
// ...
}
}