Hi!
How can I get 3d object size in cocos units?
I tried using getComponent(Collider).worldBounds.halfExtents but propably its not what I’m looking for
any other solutions?
What do you need 3d object size for?
I have to move, rotate and scale my 3d object to fit 2d UI transform. But as you can see at the screen it doesn’t fit well. In this iteration I’m using collider boundingSphere radius to get size (i don’t care much about what side of my 3d object is larger than others)
I use this code:
import { Camera, Collider, Component, Input, input, Node, Quat, RigidBody, UITransform, Vec3, view, _decorator } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('NewComponent')
export class NewComponent extends Component {
@property(Node)
object3D: Node
@property(Node)
objectUI: Node
@property(Camera)
camera: Camera
start() {
input.on(Input.EventType.TOUCH_END, this.move, this)
}
move() {
this.object3D.getComponent(Collider).enabled = false
this.object3D.getComponent(RigidBody).enabled = false
// finding rotation
const newObjectRotation = new Quat()
Quat.fromEuler(newObjectRotation, 0, 0, 0)
// finding position
let scaleX = view.getScaleX()
let scaleY = view.getScaleY()
const localPosX = this.objectUI.worldPosition.x * scaleX;
const localPosY = this.objectUI.worldPosition.y * scaleY;
const newLocal_2 = new Vec3(localPosX, localPosY, 0.5);
const newObjectPos = this.camera.screenToWorld(newLocal_2);
// finding scale
const screenHeightInUnits = this.camera.orthoHeight * 2;
const screenWidthInUnits = screenHeightInUnits * view.getVisibleSize().width / view.getVisibleSize().height
const xPixelsInUnit = view.getVisibleSize().width / screenWidthInUnits
const yPixelsInUnit = view.getVisibleSize().height / screenHeightInUnits
const contentSize = this.objectUI.getComponent(UITransform).contentSize;
const radius = this.object3D.getComponent(Collider).boundingSphere.radius
let newObjectScale: Vec3
let multiplier: number = 1
const yContentSizeInUnits = contentSize.y / yPixelsInUnit
const xContentSizeInUnits = contentSize.x / xPixelsInUnit
// you need to fit a circle on the smaller side of the sprite
if (yContentSizeInUnits <= xContentSizeInUnits) {
multiplier = yContentSizeInUnits / (radius * 2)
} else {
multiplier = xContentSizeInUnits / (radius * 2)
}
newObjectScale = new Vec3(this.object3D.worldScale).multiplyScalar(multiplier)
this.object3D.worldPosition = newObjectPos
this.object3D.worldScale = newObjectScale
this.object3D.worldRotation = newObjectRotation
}
}
Before moving:
After moving:
Btw I can use collider world bound by using:
const objectUnitSize = new Vec3(this.object3D.getComponent(Collider).worldBounds.halfExtents).multiplyScalar(2)
let newObjectScale: Vec3
let multiplier: number = 1
const yContentSizeInUnits = contentSize.y / yPixelsInUnit
const xContentSizeInUnits = contentSize.x / xPixelsInUnit
// you need to fit a circle on the smaller side of the sprite
if (yContentSizeInUnits <= xContentSizeInUnits) {
multiplier = yContentSizeInUnits / objectUnitSize.y
} else {
multiplier = xContentSizeInUnits / objectUnitSize.x
}
Somehow it’s ended up the same way as using radius
I’m going to share my project with code in case you may need this to test by yourself
NewProject_2.zip (1.6 MB)
Hi again
I made some tweeks to make the problem more realistic for my case
const halfSize = this.object3D.getComponent(Collider).worldBounds.halfExtents.multiplyScalar(2)
let newObjectScale: Vec3
let multiplier: number = 1
const yContentSizeInUnits = contentSize.y / yPixelsInUnit
const xContentSizeInUnits = contentSize.x / xPixelsInUnit
// you need to fit a circle on the smaller side of the sprite
if (yContentSizeInUnits <= xContentSizeInUnits) {
multiplier = yContentSizeInUnits / (halfSize.y * 2)
} else {
multiplier = xContentSizeInUnits / (halfSize.x * 2)
}
newObjectScale = new Vec3(this.object3D.worldScale).multiplyScalar(multiplier)
It works fine with one object:
But won’t work with other:
I guess the problem is with scaling of my object but anyway I can’t get the result I want
NewProject_2.zip (2.3 MB)






