Unity How do I set up a GUITexture as a button? - button

I added GUITexture by going to Game object>>Create Other>>GUI Texture and added its texture in the inspector what I want now is when the user touches (Game is for android and IOS) that GUITexture to move cube up I tried this code
var up : GUITexture;
var player : Rigidbody2D;
function Update () {
for (var evt : Touch in Input.touches) {
var HitTest1 = up.HitTest(evt.position);
if (evt.phase == TouchPhase.Began) {
if(HitTest1){
player.rigidbody2D.AddForce(Vector2(-2,0));
fireButton.enabled = false;
}
}
}
}
But it didn't work. What can I do?

if (GUI.Button(Rect(10,10,50,50),up))
//Code to move cube up
This will create a GUIButton out of your texture. You would need to put this into the OnGUI function in your script. Here is a link to the reference for GUIButtons: GUIButtons

In your code you have declared player as a rigidbody
var player : Rigidbody2D;
and below are trying to access its rigidbody
player.rigidbody2D.AddForce(Vector2(-2,0)); //this won't work
player.AddForce(Vector2(-2,0));//*use this instead*
OR
Try declaring player as gameobject
var player:GameObject
and add force correctly
player.rigidbody2D.AddForce(Vector2(-2,0));

Related

Applying a background for the control in an Effect in XamarinForms

I'm trying to apply a background for what ever the control the effect is attached to.
First i made the effect to apply a background for the controls that have either a Fill or Background properties in UWP.
But the problem is a lot of controls renderes to FrameworkElement in UWP. And FrameworkElement doesn't have a Background property .
In the VisualElementRenderer Xamarin forms adresses this issue be applying a background layer behind the content but this is an effect.
Is there is any way to apply a background for whatever the effect is attached to?
I'm appplying an AcrylicBrush So it must be assigned to the Control directly.
The code i written before:
try
{
Control.GetType().GetProperty("Background").SetValue(Control, brush);
}
catch
{
Control.GetType().GetProperty("Fill").SetValue(Control, brush);
}
I'm appplying an AcrylicBrush So it must be assigned to the Control directly.
You could use compositor to apply Acrylic to SpriteVisual. We use Win2D to make GaussianBlurEffect for UIElement before we have Acrylic API. Get Compositor of UIElement, and use this Compositor to CreateSpriteVisual. then set GaussianBlurEffect to hostSprite.Brush like the following.
Compositor _compositor;
SpriteVisual _hostSprite;
private void applyAcrylicAccent(Panel panel)
{
_compositor = ElementCompositionPreview.GetElementVisual(panel).Compositor;
_hostSprite = _compositor.CreateSpriteVisual();
_hostSprite.Size = new Vector2((float)panel.ActualWidth, (float)panel.ActualHeight);
var backdrop = _compositor.CreateHostBackdropBrush();
// Use a Win2D blur affect applied to a CompositionBackdropBrush.
var graphicsEffect = new GaussianBlurEffect
{
Name = "Blur",
BlurAmount = 100f,
Source = new CompositionEffectSourceParameter("backdrop")
};
var effectFactory = Window.Current.Compositor.CreateEffectFactory(graphicsEffect, new[] { "Blur.BlurAmount" });
var effectBrush = effectFactory.CreateBrush();
effectBrush.SetSourceParameter("backdrop", backdrop);
_hostSprite.Brush = effectBrush;
ElementCompositionPreview.SetElementChildVisual(panel, _hostSprite);
}
And calling it with applyAcrylicAccent(RootLayout). You also will need to handle the SizeChanged event :
private void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (_hostSprite != null)
_hostSprite.Size = e.NewSize.ToVector2();
}

Select a game object and perform actions using GUI.Button (EventTrigger)

I am currently working on a strategy game and I want to preform actions using GUI.Button on game objects. I am using ray cast and mouse click to select the object however when I click on GUI.Button to take out another action the button disappears. I want to use that button to open up another GUI.Box to show some descriptions.
I know why the button is disappearing, it is because I am projecting the ray cast to my button clicks in the update function but how can I avoid this? I also know that I have to use EventTrigger however I am not familiar with javascript event trigger, I searched online but I couldn't find any helpful javascript.
Screenshots:
Here is my script:
#HideInInspector
var isCalled:int = 0;
#HideInInspector
var scWidth:int = 0;
#HideInInspector
var scHeight:int = 0;
function Start () {
scWidth = Screen.width;
scHeight = Screen.height;
}
function Update () {
if (Input.GetMouseButtonDown(0)) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
}
function OnGUI(){
if(isCalled==1)
GUI.Button(Rect(scWidth/2,(scHeight/2)+(scHeight/4),120,120), name);
}
}
If I understood you right, the problem is that when you click on button the raycast is fired up before button click and you select different object or no object at all and button disappears or reappears but for another object, what you need to do is check if you clicked on GUI and if yes don't project the raycast that selects the objects. Here is how you are gonna do it.
var selectedUI : GameObject = EventSystem.current.currentSelectedGameObject;
if (Input.GetMouseButtonDown(0) && selectedUI) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
I work in C#, so I might have done some syntax errors, but the logic is right.
There is a good trick when using legacy GUI system to avoid raycast when mouse is over GUI elements. Using tooltip to controll if you may cast your ray =)
Something like this (I also don't work with US so may I it needs some work):
var hover : String;
function OnGUI(){
if(GUI.Button (Rect (10,10,100,20), "My Button"));
hover = GUI.tooltip;
function Update () {
if(hover != "") {
// raycast logic
}
}
If you need to avoid raycast when your "popUp" window/panel is shown but you don't want a tooltip on it you may approach using a MouseOverGUI manager too.
It is just a static or singleton holding a boolean that you will set true when your mouse is over some rect that you don't want to cast rays using Rect.Contains(Event.current.mousePosition) and to false whenever it runs out of this rect.
Use this bool with or without tooltip var to allow raycast:
if(!MouseManager.MouseOverGUI) {
// raycast logic
}
Note that creating your rect on each OnGUI cycle will difficult to catch it and control the MouseOveGUI. Also it is a bad practice for performance because OnGUI runs more than once per frame so I'll suggest you to create you rects just once (recalculate it just when needed) and pass it to your GUI elements ;)
I think the easiest way is to create a GameObject(input blocker) which is not visible but have a collider. Place it in between the camera and level objects and deactivate it. When you select a GameObject using Raycast you enable that input blocker GameObject and place it around the area of selected GameObject and GUI. Then you have to ignore the selection if raycast is collided with Input Blocker. When you deselect the Gameobject then you deactivate input blocker
You should also maintain current state of the game for example:
enum State
{
NothingSelected = 0,
GameobjectSelected,
BigMenuOpen
}
State currentState;
So according to state you can define the behavior on mouse click. Like if Full screen menu is Open then raycast does not fire.

Redrawing the globe

When toggling the visibility of 3D KmlPolygons or modifying style properties the globe doesn't update directly afterwards. Rather, you need to trigger an update by moving your mouse around. There's an internal redraw function that's only called at certain times, but I don't know how to invoke it.
To get the map to update I've made this function:
redraw : function (ge) {
ge = setDefault(ge, this.ge);
if (typeof obj == 'undefined' && ge) {
Log.info('Earth redraw');
ge.getWindow().setVisibility(false);
ge.getWindow().setVisibility(true);
} else {
Log.error('Earth redraw failed');
}
}
It toggles the window visibility and forces an update, but this causes a flash on some computers and isn't too elegant. Is there an alternative?
Try to copy the camera and set it again. I don't know if this will work, but if it works it should not make any flash
var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
ge.getView().setAbstractView(lookAt);

Check transparency

I have swf file(900x600) and main part of that file is transparense.
So I want by clicking in swf file know either user clicks on transaprent part of image or not...
I can get mouse coordinates by
event.localX
event.localY
So how to know in clicked part swf is transparent or not?
First of all, be sure, that you have some transparent sprite on background of your swf - otherwise you won't receive event.
Second, do not use pure local coordinates, they can contain local coordinates of another inner object, while you need them from root. For example, I've used stage's coordinates
If you receive mouse event, add mouse event listener to the root of that swf and write following:
var bmd:BitmapData = new BitmapData(1, 1, true, 0);
var pt:Point = new Point();
var m:Matrix = new Matrix();
m.translate(-e.stageX, -e.stageY);
bmd.draw(this, m);
var transparent:Boolean = !bmd.hitTest(pt, 0x00, pt);
trace('color: '+bmd.getPixel32(0,0).toString(16));
trace('is tranparent? ' + transparent);
bmd.dispose();
You can add an event listener on the stage for a mouse click, and check if e.target == stage.
Here is the code:
import flash.events.MouseEvent;
stage.addEventListener(MouseEvent.CLICK, hClick);
function hClick(e : MouseEvent) : void
{
trace(e.target == stage); // true if we click on the transparent zone, false if we hit a symbol on the stage.
}
Not the best or cleanest code but it should work.
This is not tested code I just whipped it up.
private function handleMouseDown(event:MouseEvent):void {
var pt:Point = new Point(event.localX, event.localY);
pt = event.target.globalToLocal(pt);
var tmp:int = int( (new uint( event.target.getPixel32(pt.x,pt.y) ).toString(16)).substr(0,2) );
if( tmp != 0 ){
trace( 'is transparent' )
}
}

Flex 3 - Image cache

I'm doing an Image Cache following this method: http://www.brandondement.com/blog/2009/08/18/creating-an-image-cache-with-actionscript-3/
I copied the two as classes, renaming them CachedImage and CachedImageMap.
The thing is that I don't want to store the image after being loaded a first time, but while the application is being loaded.
For that, I've created a function that is called by the application pre-initialize event. This is how it looks:
private function loadImages():void
{
var im:CachedImage = new CachedImage;
var sources:ArrayCollection = new ArrayCollection;
for each(var cs in divisionData.division.collections.collection.collectionSelection)
{
sources.addItem(cs.toString());
}
for each(var se in divisionData.division.collections.collection.searchEngine)
{
sources.addItem(se.toString());
}
for each( var source:String in sources)
{
im.source = source;
im.load(source);
}
}
The sources are properly retrieved.
However, even if I use the load method, I do not get the "complete" event... As if the image is not being loaded... How is that?
Any help would be appreciated.
Thanks in advance.
Regards,
BS_C3
I found the problem with my code =)
It was a declaration problem.
I moved the declaration of the cachedImage inside the for each loop where the images are loaded. So that I get something like this:
for each( var source:String in sources)
{
var im:CachedImage = new CachedImage;
im.source = source;
im.load(source);
}
And this does the trick.

Resources