Camera focus an object center - unity3d

Pick up the exactly center position of object in my code i use onmousedown function inside this function pick the click position i want center an object in the screen
private void OnMouseDown()
{
Camera.main.GetComponent<PanZoom>().thisGameObject = ParentThis.gameObject;
if (_center)
{
Debug.Log("Show Popup");
Popup.SetActive(true);
}
else
{
Vector3 groundPos = GetWorldPosAtViewportPoint(.5f, .5f);
Debug.Log(groundPos);
Debug.Log("groundPos: " + groundPos);
groundCamOffset = Camera.main.transform.position - groundPos;
Debug.Log("Camera pos " + Camera.main.transform.position);
camTarget = Camera.main.transform.position;
float mouseX = Input.mousePosition.x / Camera.main.pixelWidth;
float mouseY = Input.mousePosition.y / Camera.main.pixelHeight;
Debug.Log("Mousex " + Input.mousePosition.x + " : " + Camera.main.pixelWidth + " Mousey " + Input.mousePosition.y + " : " + Camera.main.pixelHeight);
Debug.Log("Mx " + ParentThis.transform.localPosition.x + " My " + ParentThis.transform.localPosition.y);
Vector3 clickPt = GetWorldPosAtViewportPoint(mouseX, mouseY);
camTarget = clickPt + groundCamOffset;
Go = true; // For Camera movement //!?
}
}

I would in this case advise you to read more about Cinemachine, as it has functionality where you can make it change to look at a camera target. Please note that Cinemachine must first be installed via the package manager in Unity.

Related

When loading the main menu scene in Unity, I need the player position to reset even if there's a playerprefs save

I need to reset the player's position in the main menu scene to 0,0,0, whether or not they have saved their playerprefs.
This is the code I'm using in Unity to reset the player's position when they exit to the Main Menu scene. This is a VR game. It works for players who haven't saved, but doesn't reset the position of players who have saved their playerprefs, and I don't know how to make that happen.
My reset position script:
//reset position of player in main menu scene
[SerializeField] Transform playerSpawnPosition;
[SerializeField] GameObject player;
[SerializeField] private Camera playerHead;
public void ResetPosition()
{
var rotationAngleY = playerHead.transform.rotation.eulerAngles.y
- playerSpawnPosition.rotation.eulerAngles.y;
player.transform.Rotate(0, -rotationAngleY, 0);
var distanceDifference = playerSpawnPosition.transform.position
- playerHead.transform.position;
player.transform.position += distanceDifference;
}
public void ExitToMainMenu(){
if(pauseMenu == null){
return;
}
pauseMenu.SetActive(false);
if (LeftHand && RightHand)
{
Time.timeScale = 1f;
LeftHand.transform.parent = leftparent;
RightHand.transform.parent = rightParent;
}
SceneManager.LoadScene(0,LoadSceneMode.Single);
ResetPosition();
}
My Save Player Position script:
public void SavePlayerPosition(){
hpc = FindObjectOfType<HVRPlayerController>();
if(hpc == null){
return;
}
PlayerPrefs.SetFloat("PlayerXPos",hpc.transform.position.x);
PlayerPrefs.SetFloat("PlayerYPos",hpc.transform.position.y);
PlayerPrefs.SetFloat("PlayerZPos",hpc.transform.position.z);
Vector3 v = hpc.transform.rotation.eulerAngles;
PlayerPrefs.SetFloat("PlayerYRot",v.y);
PlayerPrefs.SetString("SpawnId", "xyzSave");
Debug.Log("Saved player to position " + hpc.transform.position.x + " "
+ hpc.transform.position.y + " "+ hpc.transform.position.z + " ");
}
public void LoadPlayerPosition(){
hpc = FindObjectOfType<HVRPlayerController>();
if(hpc == null){
return;
}
playerX = PlayerPrefs.GetFloat("PlayerXPos");
playerY = PlayerPrefs.GetFloat("PlayerYPos");
playerZ = PlayerPrefs.GetFloat("PlayerZPos");
playerYRot = PlayerPrefs.GetFloat("PlayerYRot",hpc.transform.rotation.y);
Debug.Log("Loaded player position " + playerX + " "
+ playerY + " "+ playerZ);
}
You're likely calling LoadPlayerPosition() after every position reset. If it's called in a Start() method in a monobehaviour, it's likely going to get called after ResetPosition().
If this is the case, the 0,0,0 values for your players position might not even be set by ResetPosition, instead they're set to the default values returned by PlayerPrefs.GetFloat(), '0.0'.
To Test
Put breakpoints on ResetPosition(); and hpc = FindObjectOfType<HVRPlayerController>();. In the case where a player has set player prefs, I have a feeling your will observe that ResetPosition(); is called before hpc = FindObjectOfType<HVRPlayerController>();.
To Fix
This is a bit tricky. The solution I'd play around with is tying the two functions together in another function call. The function would have a parameter isMainMenuReset. If it's true, call ResetPosition(), else, call LoadPlayerPosition(). You'd have to replace all LoadPlayerPosition() calls in your codebase with this new function call.

Underlining with pdfnet results in different line thickness

The code that i use for underlining a selection of text. I begin calling the addUnderline() method, the other methods are helper methods.
private pdftron.SDF.Obj CreateUnderlineAppearance(pdftron.PDF.Rect bbox)
{
ElementBuilder builder = new ElementBuilder();
ElementWriter writer = new ElementWriter();
builder.PathBegin();
builder.MoveTo(bbox.x1, bbox.y1);
builder.LineTo(bbox.x2, bbox.y1);
Element line = builder.PathEnd();
//Set color attributes for the line...
line.SetPathFill(false);
line.SetPathStroke(true);
GState gs = line.GetGState();
gs.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
gs.SetStrokeColor(new ColorPt(0, 0, 0)); // black
gs.SetLineWidth(2);
writer.Begin(m_document);
writer.WriteElement(line);
pdftron.SDF.Obj stm = writer.End();
builder.Dispose();
writer.Dispose();
// Set the bounding box
stm.PutRect("BBox", bbox.x1, bbox.y1, bbox.x2, bbox.y2);
stm.PutName("Subtype", "Form");
return stm;
}
public Annot CreateUnderlineAnnot(pdftron.PDF.Rect rect)
{
Annot underlineAnnot = Annot.Create(m_document, Annot.Type.e_Underline, rect);
underlineAnnot.SetAppearance(CreateUnderlineAppearance(rect));
return underlineAnnot;
}
public void AddUnderline()
{
if (m_document != null)
{
PDFViewCtrl.Selection selection = m_pdfViewer.GetSelection();
int pageNumber = selection.GetPageNum();
double[] quads = selection.GetQuads();
int numQuads = quads.Length / 8;
if (quads.Length % 8 == 0) //must have at least 8 points to be valid
{
Console.WriteLine("GetRectsFromQuads - numQuads: " + numQuads.ToString());
for (int i = 0; i < numQuads; i++)
{
Rect selectionRect = GetSelectionRect(ref quads, i);
//Console.WriteLine("GetRectsFromQuads - aRect: " + rectX1.ToString() + " | " + rectY1.ToString() + " | " + rectX2.ToString() + " | " + rectY2.ToString());
Annot underlineAnnot = CreateUnderlineAnnot(selectionRect);
m_pdfViewer.AddUnderlineAnnotationToPage(underlineAnnot, pageNumber);
//m_pdfViewer.Refresh(); --> to see how this algorithm works when debugging
}
m_pdfViewer.RefreshAnnotations();
}
}
}
You can see in the image if you look closely that some lines are thicker or thinner than others. Is this fixable? by the way, when i zoom in/out the problem is gone...
You need to set the following on your pdf view control:
PDFViewCtrl.SetThinLineAdjustment(true, true);
That will remove the aliasing on the lines, and mean all lines that are 1.5px are 1px, and so on. See here: https://www.pdftron.com/pdfnet/mobile/docs/WinRT/html/M_pdftron_PDF_PDFViewCtrl_SetThinLineAdjustment.htm

css style transform

I wanted to be able to put into effect the css transform property depending on the size of a container with respect to the size of the enclosing window.
With the following code, scaleCameraShutter() is called. Zooming does occur with the re-written code for scaleCameraShutter()and the scaling is accurate.
Here's the only remaining problem = window resizes and so does the container. THEN, I do a reload of the window and the correct zooming totally disappears. In short, the zooming is only temporary, not permanent??
Since this Board thrives on code, the .css specs are at the bottom ...
$(window).bind('resize', function() {
scaleCameraShutter(); // below, container is GLOBAL
});
I call:
function scaleCameraShutter() {
// .width() returns "###px"
// value before scaling
var containerWidth = parseInt( container.width() );
var windowWidth = parseInt( $(window).width() );
var theScale = windowWidth/containerWidth;
var maxContainerWidth = 480;
if (windowWidth > maxContainerWidth)
{
theScale = maxContainerWidth/containerWidth;
}
// Let the Browser pick the parm it accepts:
// IE 10 and Firefox
container.css("-transform" , "scale(" + theScale + ", " + theScale + ")");
// IE 9
container.css("-ms-transform" , "scale(" + theScale + ", " + theScale + ")");
// Firefox
container.css("-moz-transform" , "scale(" + theScale + ", " + theScale + ")");
// Chrome and Safari
container.css("-webkit-transform", "scale(" + theScale + ", " + theScale + ")");
// Opera
container.css("-o-transform" , "scale(" + theScale + ", " + theScale + ")");
}
Last, here's the css:
#container {
position: relative;
margin: 0 auto;
width: 30.00em;
height: 22.50em;
}
As Far as I know, you are passing only one value to SCALE. Try doing one of the following:
scale(x,y) Defines a 2D scale transformation
scale3d(x,y,z) Defines a 3D scale transformation
scaleX(x) Defines a scale transformation by giving a value for the X-axis
scaleY(y) Defines a scale transformation by giving a value for the Y-axis
scaleZ(z) Defines a 3D scale transformation by giving a value for the Z-axis
http://www.w3schools.com/cssref/css3_pr_transform.asp
good luck.

MenuItemLabel callback not working, never calls the callback, but the MenuItemImage works

Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
Vector<MenuItem*> menuItems;
auto label = Label::createWithTTF("Space Combat", "fonts/Marker Felt.ttf", 24);
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - label->getContentSize().height));
this->addChild(label, 1);
auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(MainMenu::menuCloseCallback, this));
closeItem->setPosition(origin.x + visibleSize.width - closeItem->getContentSize().width/2,
origin.y + closeItem->getContentSize().height/2);
menuItems.pushBack(closeItem);
auto playLabel = Label::createWithTTF("Play", "fonts/Marker Felt.ttf", 24);
playLabel->setPosition(Vec2(origin.x + visibleSize.width/2, origin.y + visibleSize.height - label->getContentSize().height *2));
auto playItem = MenuItemLabel::create(playLabel, CC_CALLBACK_1(MainMenu::menuPlayCallback, this));
menuItems.pushBack(playItem);
auto menu = Menu::create();
menu->addChild(closeItem);
menu->addChild(playItem);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
this->addChild(sprite, 0);
return true;
}
The above code will call my menuCloseCallback when the MenuItemImage is clicked on, but won't do the same for the MenuItemLabel.
Figured it out. I was positioning the label, but the menu item was being placed in the default location of 0,0 anchor 0,0. Once i added the label and positioned the menu item, all was well.

Compass to annotation with Titanium

I'am trying to build a compass that heading to a annotation with Titanium on a map. It's already succeeded me to build a normal compass with the compass function in Titanium.
I am unable to make the compass point the right direction from the location. Has anyone a script or example what works?
if (Titanium.Geolocation.hasCompass){
var transform = Ti.UI.create2DMatrix();
// Settings
Titanium.Geolocation.showCalibration = true;
Titanium.Geolocation.headingFilter = 0;
Ti.Geolocation.getCurrentHeading(function(e){
if (e.error){
Titanium.API.info("error: " + e.error);
return;
}
var animationNorth = Titanium.UI.createAnimation({
transform : transform.rotate(e.heading.trueHeading),
duration : 50
});
// Rotate image to north
compassNorth.animate(animationNorth);
headingLabel.setText('geo - current heading: ' + e.heading.trueHeading);
});
Titanium.Geolocation.addEventListener('heading', function(e){
if (e.error){
Titanium.API.info("error: " + e.error);
return;
}
var animationNorth = Titanium.UI.createAnimation({
transform : transform.rotate(e.heading.trueHeading),
duration : 50
});
// Rotate image to north
compassNorth.animate(animationNorth);
headingLabel.setText('geo - current heading: ' + e.heading.trueHeading);
});
} else {
headingLabel.setText("No Compass on device");
}