首先让我们一起看看最终实现效果吧
预制体的结构如下:
1.photograph脚本-负责配置相关属性与打开交互UI
2.photographUI脚本-负责实现交互相关逻辑
3.将photograph脚本挂载在预制体上保存即可
1
2
photograph脚本代码如下
/**
* AUTHOR: 疏影横斜水清浅
* TIME: 2023.02.24-10.46.01
*/
import photographUI from "./photographUI";
@Core.Class
export default class photograph extends Core.Script {
@Core.Property({ displayName: "远近距离", group: "拍照动效属性", })
public lengthArm: number = 300;
@Core.Property({ displayName: '白光起始透明度', group: "拍照动效属性" })
public initRenderOpacity: number = 0.1;
@Core.Property({ displayName: '白光结束透明度', group: "拍照动效属性" })
public endRenderOpacity: number = 0.65;
@Core.Property({ displayName: '渐变到白光时间:单位-毫秒', group: "拍照动效属性" })
public moveWhiteTime: number = 200;
@Core.Property({ displayName: '白光停留时间:单位-毫秒', group: "拍照动效属性" })
public stayWhilteTime: number = 3;
@Core.Property({ displayName: '图片移动时间:单位-毫秒', group: "拍照动效属性" })
public imageMoveTime: number = 1000;
@Core.Property({ displayName: '最终图片的比例', group: "拍照动效属性" })
public endImageProportion: number = 0.65;
@Core.Property({ displayName: '最终图片旋转角度', group: "拍照动效属性" })
public endImageRotation: number = -8;
/** 当脚本被实例后,会在第一帧更新前调用此函数 */
protected onStart(): void {
if (Util.SystemUtil.isClient()) {
UI.UIManager.instance.show(photographUI, this.lengthArm,this.initRenderOpacity, this.endRenderOpacity,
this.moveWhiteTime, this.stayWhilteTime, this.imageMoveTime, this.endImageProportion, this.endImageRotation);
}
}
} photographUI脚本代码如下
/**
* AUTHOR: 疏影横斜水清浅
* TIME: 2023.02.24-10.46.01
*/
import DefaultUI_Generate from "../../../JavaScripts/ui-generate/DefaultUI_generate";
import photographUI_Generate from "./ui-generate/photographUI_generate";
export default class photographUI extends photographUI_Generate {
private isFreeCamera = false;
/**
* 构造UI文件成功后,在合适的时机最先初始化一次
*/
protected onStart() {
//设置能否每帧触发onUpdate
this.canUpdate = true;
this.layer = UI.UILayerMiddle;
this.initCamera();
this.UIBtnEventBind();
}
onShow(_lengthArm: number, _initRenderOpacity: number, _endRenderOpacity: number,
_moveWhiteTime: number, _stayWhilteTime: number, _imageMoveTime: number, _endImageProportion: number, _endImageRotation: number) {
this.lengthArm = _lengthArm;
this.initRenderOpacity = _initRenderOpacity;
this.endRenderOpacity = _endRenderOpacity;
this.moveWhiteTime = _moveWhiteTime;
this.stayWhilteTime = _stayWhilteTime;
this.imageMoveTime = _imageMoveTime;
this.endImageProportion = _endImageProportion;
this.endImageRotation = _endImageRotation;
//相机臂相关参数初始化
this.bar_lengthCamera.currentValue = 0.5;
this.oldBarCur = this.bar_lengthCamera.currentValue;
//相关参数初始化
this.mSlotCanvasInitSize = WindowUtil.getViewportSize();
this.mSlotCanvasToSize = new Type.Vector2(this.mSlotCanvasInitSize.x * this.endImageProportion, this.mSlotCanvasInitSize.y * this.endImageProportion);
this.mSlotCanvasToPosition = new Type.Vector2(this.mSlotCanvasInitSize.x / 2 - this.mSlotCanvasToSize.x / 2, this.mSlotCanvasInitSize.y / 2 - this.mSlotCanvasToSize.y / 2);
this.slotCanvasData = {
imagePosition: Type.Vector2.zero,
imageSize: this.mSlotCanvasInitSize.clone(), imageRotation: 0
}
}
//记录原先的进度条值
private oldBarCur: number;
//为界面上的UI进度条等绑定相关函数
UIBtnEventBind() {
this.btn_camera.onClicked.add(() => {
this.btn_camera.visibility = UI.SlateVisibility.Collapsed;
this.img_Btncamera.visibility = UI.SlateVisibility.Collapsed;
this.cameraCanvas.visibility = UI.SlateVisibility.Visible;
Gameplay.getCurrentPlayer().character.moveEnable = false;
this.startFreeCamera();
//相机臂相关参数初始化
this.bar_lengthCamera.currentValue = 0.5;
this.oldBarCur = this.bar_lengthCamera.currentValue;
});
this.btn_close.onClicked.add(() => {
this.btn_camera.visibility = UI.SlateVisibility.Visible;
this.img_Btncamera.visibility = UI.SlateVisibility.SelfHitTestInvisible;
this.cameraCanvas.visibility = UI.SlateVisibility.Collapsed;
this.canvasPircture.visibility = UI.SlateVisibility.Collapsed;
this.text_path.visibility = UI.SlateVisibility.Collapsed;
Gameplay.getCurrentPlayer().character.moveEnable = true;
this.stopFreeCamera();
});
this.virtualJoystickPanel.onInputDir.add((vec2: Type.Vector2) => {
this.directionOfXY = vec2.normalize();
});
this.btn_shoot.onClicked.add(() => {
this.startShotTween();
});
this.btn_closePircture.onClicked.add(() => {
this.canvasPircture.visibility = UI.SlateVisibility.Collapsed;
this.text_path.visibility = UI.SlateVisibility.Collapsed;
});
this.bar_lengthCamera.sliderMinValue = 0;
this.bar_lengthCamera.sliderMaxValue = 1;
this.bar_lengthCamera.onSliderValueChanged.add((value) => {
let newValue = this._cameraSystem.targetArmLength + (value - this.oldBarCur) * this.lengthArm;
this._cameraSystem.targetArmLength = newValue;
this.oldBarCur = this.bar_lengthCamera.currentValue;
});
}
//#region 相机移动相关
private _cameraAnchor: Core.GameObject
private _cameraSystem: Gameplay.CameraSystem;
private _oldCameraSetting: Gameplay.CameraSystemData;
initCamera() {
this._cameraAnchor = Core.GameObject.spawnGameObject("Anchor");
this._cameraSystem = Gameplay.getCurrentPlayer().character.cameraSystem;
}
startFreeCamera() {
this._cameraSystem.followTargetEnable = false;
this._cameraAnchor.transform = Gameplay.getCurrentPlayer().character.cameraSystem.cameraWorldTransform;
this._oldCameraSetting = this._cameraSystem.getCurrentSettings();
this._cameraSystem.applySettings(this.FREE_VIEW_CAMERA_SETTING);
this._cameraSystem.attachToGameObject(this._cameraAnchor);
// let radian = Math.PI / 2;
// let _cameraAnchorForRightVectorX = this._cameraAnchor.forwardVector.x * Math.cos(radian) - this._cameraAnchor.forwardVector.y * Math.sin(radian);
// let _cameraAnchorForRightVectorY = this._cameraAnchor.forwardVector.x * Math.sin(radian) + this._cameraAnchor.forwardVector.y * Math.cos(radian);
// this._cameraAnchorForRightVector = new Type.Vector(_cameraAnchorForRightVectorX, _cameraAnchorForRightVectorY, 0);
//因为sin cos 九十度的特殊性,简化成下面这一句
this._cameraAnchorForRightVector = new Type.Vector(-this._cameraAnchor.forwardVector.y, this._cameraAnchor.forwardVector.x, 0);
this.isFreeCamera = true;
}
stopFreeCamera() {
this.isFreeCamera = false;
this._cameraSystem.applySettings(this._oldCameraSetting);
this._cameraSystem.cancelCameraLockTarget();
this._cameraSystem.followTargetEnable = true;
}
private moveLocation = Type.Vector.zero;
/**上升下落速度 */
private speedZ = 5;
/**X,Y移动 */
private directionOfXY = Type.Vector2.zero;
/**X,Y移动速度 */
private _speedXY = 5;
private _cameraAnchorForRightVector;
onUpdate() {
if (this.isFreeCamera) {
if (this.btn_up.isPressed()) {
this.moveLocation.z += this.speedZ;
}
if (this.btn_down.isPressed()) {
this.moveLocation.z -= this.speedZ;
}
this.moveLocation.add(this._cameraAnchor.forwardVector.multiply(
this.directionOfXY.y * this._speedXY));
this.moveLocation.add((this._cameraAnchorForRightVector).clone().multiply(
this.directionOfXY.x * this._speedXY));
this._cameraAnchor.worldLocation = this._cameraAnchor.worldLocation.add(this.moveLocation);
this.moveLocation = Type.Vector.zero;
}
}
// 自由视角时摄像机设置(不能将视角K为上下90°(P分量),否则重置摄像机将出现异常)
private readonly FREE_VIEW_CAMERA_SETTING: Gameplay.CameraSystemData = {
/** 摄像机相对Transform */
cameraRelativeTransform: new Type.Transform(),
/** 摄像机世界Transform */
cameraWorldTransform: new Type.Transform(),
/** 投影模式 */
cameraProjectionMode: Gameplay.CameraProjectionMode.Perspective,
/** 正交宽度 */
orthoWidth: 512,
/** 正交视图近平面距离 */
orthoNearClipPlane: 0,
/** 正交视图远平面距离 */
orthoFarClipPlane: 2097152,
/** 距离调整 */
targetArmLength: 0,
/** 开启摄像机位置延迟 */
enableCameraLocationLag: false,
/** 摄像机位置延迟速度 */
cameraLocationLagSpeed: 0,
/** 开启摄像机旋转延迟 */
enableCameraRotationLag: false,
/** 摄像机旋转延迟速度 */
cameraRotationLagSpeed: 0,
/** 视场 */
cameraFOV: 90,
/** 摄像机位置模式 */
cameraLocationMode: Gameplay.CameraLocationMode.LocationFollow,
/** 摄像机朝向模式 */
cameraRotationMode: Gameplay.CameraRotationMode.RotationControl,
/** 是否有摄像机碰撞 */
enableCameraCollision: false,
/** 挂点位置偏移 */
targetOffset: new Type.Vector(0, 0, 0),
/** 摄像机位置偏移 */
slotOffset: new Type.Vector(0, 0, 0),
/** 向上限制角度 */
cameraUpLimitAngle: 89.9,
/** 向下限制角度 */
cameraDownLimitAngle: 89.9,
/** 是否开启物体透明 */
enableFadeEffect: false,
/** 物体透明度 */
fadeEffectValue: 0,
/** 开启碰撞抬高 */
enableRaiseCamera: false,
/** 抬高高度 */
raiseCameraHeight: 0
};
//#endregion
//#region 拍照截图相关
//相关属性参数暴露
//远近距离拉扯
private lengthArm;
//白光起始透明度
private initRenderOpacity;
//白光结束透明度
private endRenderOpacity;
//渐变到白光时间:单位-毫秒
private moveWhiteTime;
//白光停留时间:单位-毫秒
private stayWhilteTime;
//图片移动时间:单位-毫秒
private imageMoveTime;
//最终图片的比例
private endImageProportion;
//最终图片旋转角度
private endImageRotation;
//#endregion
//#region 拍照闪烁动效
private _tween_Shot: Util.TweenUtil.Tween<{ maskNum: number }> = null;
private startShotTween() {
this.img_mask.renderOpacity = 0;
this.img_mask.visibility = UI.SlateVisibility.SelfHitTestInvisible;
if (this._tween_Shot === null) {
this._tween_Shot = new Util.TweenUtil.Tween({ maskNum: this.initRenderOpacity });
this._tween_Shot.to({ maskNum: this.endRenderOpacity }, this.moveWhiteTime);
/**设置运行逻辑 */
this._tween_Shot.onUpdate((data) => {
this.img_mask.renderOpacity = data.maskNum;
}).onComplete(() => {
setTimeout(() => {
this.img_mask.renderOpacity = 0;
this.img_mask.visibility = UI.SlateVisibility.Collapsed;
MobileEditor.screenShot(Util.WindowUtil.getViewportSize(),
Type.Vector2.zero, Util.WindowUtil.getViewportSize().x, WindowUtil.getViewportSize().y, (str: string) => {
this.setSlotImg(str);
this.text_path.visibility = UI.SlateVisibility.Visible;
this.text_path.text = "截图保存路径为:" + str;
})
}, this.stayWhilteTime);
});
/**设置变化曲线 */
this._tween_Shot.easing(Util.TweenUtil.Easing.Exponential.In);
this._tween_Shot.start();
} else {
this._tween_Shot.start();
}
}
/**
* 照片动效
* @param path
*/
private _tween_showImage: Util.TweenUtil.Tween<{ imagePosition: Type.Vector2, imageSize: Type.Vector2, imageRotation: number }> = null;
private mSlotCanvasInitSize: Type.Vector2;
private mSlotCanvasToSize: Type.Vector2;
private mSlotCanvasToPosition: Type.Vector2;
private slotCanvasData;
private setSlotImg(path: string) {
this.canvasPircture.position = Type.Vector2.zero;
this.canvasPircture.size = this.mSlotCanvasInitSize;
this.canvasPircture.renderTransformAngle = 0;
this.canvasPircture.visibility = UI.SlateVisibility.SelfHitTestInvisible;
this.img_showPircture.setImageByFile(path);
if (this._tween_showImage === null) {
this._tween_showImage = new Util.TweenUtil.Tween(this.slotCanvasData);
this._tween_showImage.to({
imagePosition: this.mSlotCanvasToPosition.clone(),
imageSize: this.mSlotCanvasToSize.clone(), imageRotation: this.endImageRotation
}, this.imageMoveTime);
this._tween_showImage.onUpdate((data) => {
this.canvasPircture.position = data.imagePosition;
this.canvasPircture.size = data.imageSize;
this.canvasPircture.renderTransformAngle = data.imageRotation;
});
this._tween_showImage.start();
} else {
this.slotCanvasData.imagePosition.set(0, 0);
this.slotCanvasData.imageSize.set(this.mSlotCanvasInitSize.x, this.mSlotCanvasInitSize.y)
this.slotCanvasData.imageRotation = 0;
this._tween_showImage.start();
}
}
//#endregion
} 实现的预制体:
photograph.zip
(11.6 KB, 下载次数: 68)
|