解决wordpress无法上传2M以上大文件大图片的方法
修改/etc/php.ini文件
upload_max_filesize = 128M
post_max_size = 128M
max_execution_time = 300
重启apache服务
service php-fpm restart
如果报错:php-fpm.service not found 的话,可以查看服务器/etc/init.d/下面,对应的php的fpm名称,有时候会出现带版本好的情况,比如php7.2-fpm之类的,就执行
service php7.2-fpm restart
转:Unity相机跟随多种实现方式
转自:https://blog.csdn.net/qq_37310110/article/details/94007394
一:设置目标物为相机的父节点
描述:最简单,最基础,效果最不理想,锁死跟随视角
二:常规设置固定相对向量偏移
描述:推荐指数***,代码实现简,效果比较生硬
public Transform target;
private Vector3 offset;
void Start()
{
//设置相对偏移
offset = target.position - this.transform.position;
}
void Update()
{
//更新位置
this.transform.position = target.position - offset;
}
三:添加旋转角度
描述:推荐指数***,在二的基础上添加距离差值和旋转角度差值,效果流畅
private Vector3 offset;//相机相对于玩家的位置
public Transform target;
private Vector3 pos;
public float speed = 2;
private void Start()
{
offset = transform.position - target.position;
}
// Update is called once per frame
void Update()
{
pos = target.position + offset;
this.transform.position = Vector3.Lerp(transform.position, pos, speed * Time.deltaTime);//调整相机与玩家之间的距离
Quaternion angel = Quaternion.LookRotation(target.position - transform.position);//获取旋转角度
transform.rotation = Quaternion.Slerp(transform.rotation, angel, speed * Time.deltaTime);
}
四: 第三背后视角
描述:推荐指数*****,流畅参数可调。对相机的位置实时计算
public Transform target;
public float distanceUp = 10f;//相机与目标的竖直高度参数
public float distanceAway = 10f;//相机与目标的水平距离参数
public float smooth = 2f;//位置平滑移动插值参数值
public float camDepthSmooth = 20f;
void Update()
{
// 鼠标轴控制相机的远近
if ((Input.mouseScrollDelta.y < 0 && Camera.main.fieldOfView >= 3) || Input.mouseScrollDelta.y > 0 && Camera.main.fieldOfView <= 80)
{
Camera.main.fieldOfView += Input.mouseScrollDelta.y * camDepthSmooth * Time.deltaTime;
}
}
void LateUpdate()
{
//计算出相机的位置
Vector3 disPos = target.position + Vector3.up * distanceUp - target.forward * distanceAway;
transform.position = Vector3.Lerp(transform.position, disPos, Time.deltaTime * smooth);
//相机的角度
transform.LookAt(target.position);
}
五:自由 视角
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class target_control : MonoBehaviour {
public Transform _target;
public float distance = 50.0f;
public float xSpeed = 250.0f;
public float ySpeed = 120.0f;
public int yMinLimit = -20;
public int yMaxLimit = 80;
private bool orbit = false;
private bool pan = false;
private bool zoom = false;
private float zoomValue = 0;
public float orbitDampX = 0.0f;
public float orbitDampY = 0.0f;
float panDampX = 0.0f;
float panDampY = 0.0f;
public float zoomDamp = 0.0f;
public float dampingTime = 0.0f;
public float x = 180.0f;
public float y = 0.0f;
public int planFactor = 5;
public float zoomFactor = 2.0f;
public Vector2 distLimit;
public static Quaternion _rotation;
public static Vector3 _position;
public static target_control _target_control;
public float _z_distance;
private Vector3 angles;
private Vector2 oldPosition1;
private Vector2 oldPosition2;
public float _target_distance = 5;
private float target_x;
private float target_y;
private Vector3 _target_pos = Vector3.zero;
public bool change_distance()
{
distance = Mathf.Lerp(distance, _target_distance, 0.04f);
Debug.Log(distance + "/" + _target_distance);
updateCamera();
if (Mathf.Abs(distance - _target_distance) < 0.01f)
return false;
return true;
}
public bool change_distance(float _dis)
{
distance = Mathf.Lerp(distance, _dis, 0.004f);
updateCamera();
if (Mathf.Abs(distance - _dis) < 0.01f)
return false;
return true;
}
void Start()
{
_target_distance = distance;
_z_distance = distance;
angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
// Make the rigid body not change rotation
if (GetComponent<Rigidbody>())
GetComponent<Rigidbody>().freezeRotation = true;
}
// Update is called once per frame
void LateUpdate () {
if (EventSystem.current.IsPointerOverGameObject()||_target ==null)
{
return;
}
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
orbit = true;
}
else
{
orbit = false;
}
}
else
{
orbit = false;
}
if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
if (isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
zoomValue = 0.1f;
zoom = true;
}
else
{
zoomValue = -0.1f;
zoom = true;
}
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
else
{
zoom = false;
}
}
else
{
zoom = false;
}
}
else if (Application.platform == RuntimePlatform.Android)
{
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
orbit = true;
}
else
{
orbit = false;
}
}
else
{
orbit = false;
}
if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
if (isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
zoomValue = 0.1f;
zoom = true;
}
else
{
zoomValue = -0.1f;
zoom = true;
}
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
else
{
zoom = false;
}
}
else
{
zoom = false;
}
}
else
{
if (Input.GetMouseButton(1))
{
orbit = true;
}
else
{
orbit = false;
}
if (Input.GetAxisRaw("Mouse ScrollWheel") != null)
{
zoomValue = Input.GetAxisRaw("Mouse ScrollWheel");
zoom = true;
}
else
{
zoom = false;
}
}
if (orbit)
{
orbitDampX = Mathf.Lerp(orbitDampX, Input.GetAxis("Mouse X"), dampingTime * Time.deltaTime);
orbitDampY = Mathf.Lerp(orbitDampY, Input.GetAxis("Mouse Y"), dampingTime * Time.deltaTime);
}
else
{
orbitDampX = Mathf.Lerp(orbitDampX, 0, dampingTime * Time.deltaTime);
orbitDampY = Mathf.Lerp(orbitDampY, 0, dampingTime * Time.deltaTime);
}
if (zoom)
{
zoomDamp = Mathf.Lerp(zoomDamp, zoomValue, dampingTime * Time.deltaTime);
}
else
{
zoomDamp = Mathf.Lerp(zoomDamp, 0, dampingTime * Time.deltaTime);
}
if (!checkLerp(orbitDampX, 0) || !checkLerp(orbitDampY, 0))
{
doOrbit();
}
if (!checkLerp(zoomDamp, 0))
{
doZoom();
}
}
bool isEnlarge(Vector2 oP1,Vector2 oP2 , Vector2 nP1, Vector2 nP2 )
{
var leng1 =Mathf.Sqrt((oP1.x-oP2.x)*(oP1.x-oP2.x)+(oP1.y-oP2.y)*(oP1.y-oP2.y));
var leng2 =Mathf.Sqrt((nP1.x-nP2.x)*(nP1.x-nP2.x)+(nP1.y-nP2.y)*(nP1.y-nP2.y));
if(leng1<leng2)
{
//big
return true;
}else
{
//small
return false;
}
}
bool checkLerp(float a,float b)
{
if (Mathf.Approximately(a, b))
{
return true;
}
return false;
}
void doOrbit()
{
if (_target)
{
x += orbitDampX * xSpeed * 0.02f;
y -= orbitDampY * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
updateCamera();
}
}
void doZoom()
{
distance -= zoomDamp * zoomFactor;
distance = Mathf.Clamp(distance, -distLimit.x, distLimit.y);
updateCamera();
}
void updateCamera()
{
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * new Vector3(0.0f, 0.0f, -distance) + _target.position;
transform.rotation = rotation;
transform.position = position;
}
static float ClampAngle (float angle,float min,float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}
vue-cli3构建的vue项目使用babel-polyfill兼容安卓低版本浏览器
vue-cli2构建的项目有很多教程写babel-polyfill,而最近我用了一个新的vue-cli3构建的项目,在兼容低版本安卓浏览器时遇到的问题,做一下记录。
一、babel-polyfill
IE 11版本浏览器不支持ES6百分之85%的语法规范,在vue项目中选择使用babel-polyfill兼容语法。
(1)安装babel-polyfill
npm install babel-polyfill --save-dev
(2)main.js
import 'babel/polyfill'
或者
import '@babel/polyfill'
这里尽可能在首行引入;注意一下node_module中polyfill的文件路径,有的可能是 import '@babel/polyfill' 这种情况。
(3)babel.config.js
配置内容如下:
module.exports = {
presets: [
['@vue/app', {
useBuiltIns: 'entry'
}]
]
}
(4)vue.config.js
链式webpack配置函数,配置内容如下:
// module.exports内添加
chainWebpack (config) {
config.entry('main').add('babel-polyfill')
}
Mac系统 macOS big sur 破解版软件显示:『“XXX.app”已损坏,无法打开。 您应该将它移到废纸篓。』的解决方法
sudo xattr -d com.apple.quarantine /Applications/你的app名字.app
vue项目实战:封装websocket请求(转载)
项目中需要用到websocket,网上找到一个简单又感觉还不错的封装,怕丢失了,特转载如下:
本文转载链接:https://blog.csdn.net/m0_38134431/article/details/105794108
前言:
如果项目中多个组件都使用到WebSocket请求,那么我们需要对WebSocket进行封装,方便我们使用。
下面我根据我的项目结构来创建文件和引入文件,大家注意一下自己项目结构。
一、在utils目录下创建websocket.js文件
import { Message } from 'element-ui'
import { getToken } from '@/utils/authToken' // 与后端的协商,websocket请求需要带上token参数
let websock = null
let messageCallback = null
let errorCallback = null
let wsUrl = ''
// 接收ws后端返回的数据
function websocketonmessage (e) {
messageCallback(JSON.parse(e.data))
}
/**
* 发起websocket连接
* @param {Object} agentData 需要向后台传递的参数数据
*/
function websocketSend (agentData) {
// 加延迟是为了尽量让ws连接状态变为OPEN
setTimeout(() => {
// 添加状态判断,当为OPEN时,发送消息
if (websock.readyState === websock.OPEN) { // websock.OPEN = 1
// 发给后端的数据需要字符串化
websock.send(JSON.stringify(agentData))
}
if (websock.readyState === websock.CLOSED) { // websock.CLOSED = 3
console.log('websock.readyState=3')
Message.error('ws连接异常,请稍候重试')
errorCallback()
}
}, 500)
}
// 关闭ws连接
function websocketclose (e) {
// e.code === 1000 表示正常关闭。 无论为何目的而创建, 该链接都已成功完成任务。
// e.code !== 1000 表示非正常关闭。
if (e && e.code !== 1000) {
Message.error('ws连接异常,请稍候重试')
errorCallback()
}
}
// 建立ws连接
function websocketOpen (e) {
// console.log('ws连接成功')
}
// 初始化weosocket
function initWebSocket () {
if (typeof (WebSocket) === 'undefined') {
Message.error('您的浏览器不支持WebSocket,无法获取数据')
return false
}
const token = 'JWT=' + getToken()
// ws请求完整地址
const requstWsUrl = wsUrl + '?' + token
websock = new WebSocket(requstWsUrl)
websock.onmessage = function (e) {
websocketonmessage(e)
}
websock.onopen = function () {
websocketOpen()
}
websock.onerror = function () {
Message.error('ws连接异常,请稍候重试')
errorCallback()
}
websock.onclose = function (e) {
websocketclose(e)
}
}
/**
* 发起websocket请求函数
* @param {string} url ws连接地址
* @param {Object} agentData 传给后台的参数
* @param {function} successCallback 接收到ws数据,对数据进行处理的回调函数
* @param {function} errCallback ws连接错误的回调函数
*/
export function sendWebsocket (url, agentData, successCallback, errCallback) {
wsUrl = url
initWebSocket()
messageCallback = successCallback
errorCallback = errCallback
websocketSend(agentData)
}
/**
* 关闭websocket函数
*/
export function closeWebsocket () {
if (websock) {
websock.close() // 关闭websocket
websock.onclose() // 关闭websocket
}
}
二、在vue组件中使用WebSocket封装好的功能
<template>
<div>
<button @click="requstWs">点击发起websocket请求</button>
</div>
</template>
<script>
import { sendWebsocket, closeWebsocket } from '@/utils/websocket.js'
export default {
beforeDestroy () {
// 页面销毁时关闭ws。因为有可能ws连接接收数据尚未完成,用户就跳转了页面
// 在需要主动关闭ws的地方都可以调用该方法
closeWebsocket()
},
methods: {
// ws连接成功,后台返回的ws数据,组件要拿数据渲染页面等操作
wsMessage (data) {
const dataJson = data
console.log(dataJson)
// 这里写拿到数据后的业务代码
},
// ws连接失败,组件要执行的代码
wsError () {
// 比如取消页面的loading
},
requstWs () {
// 防止用户多次连续点击发起请求,所以要先关闭上次的ws请求。
closeWebsocket()
// 跟后端协商,需要什么参数数据给后台
const obj = {
monitorUrl: 'xxxxxxxxxxxxx',
userName: 'xxxxxxxxxx'
}
// 发起ws请求
sendWebsocket('ws://test.ws.com', obj, this.wsMessage, this.wsError)
}
}
}
</script>
介绍WebSocket对象中的readyState属性
WebSocket的readyState属性用来定义连接状态,该属性的值有下面几种:
0 :对应常量 CONNECTING
正在建立连接连接,还没有完成。
1 :对应常量 OPEN
连接成功建立,可以进行通信。
2 :对应常量 CLOSING
连接正在进行关闭握手,即将关闭。
3 : 对应常量 CLOSED
连接已经关闭或者根本没有建立。
介绍WebSocket断开连接onclose的重要信息错误状态码
WebSocket断开时,会触发CloseEvent, CloseEvent会在连接关闭时发送给使用 WebSockets 的客户端. 它在 WebSocket 对象的 onclose 事件监听器中使用。CloseEvent的code字段表示了WebSocket断开的原因。可以从该字段中分析断开的原因。
CloseEvent有三个字段需要注意, 通过分析这三个字段,一般就可以找到断开原因。
CloseEvent.code: code是错误码,是整数类型
CloseEvent.reason: reason是断开原因,是字符串
CloseEvent.wasClean: wasClean表示是否正常断开,是布尔值。一般正常断开时,该值为true
如下是在关闭ws连接的时候打印出来的CloseEvent对象:
关闭状态码表
下面标红的状态码是我在项目中测试遇到过的。
状态码 描述
0–999 保留段, 未使用
1000 正常关闭; 无论为何目的而创建, 该链接都已成功完成任务.
1001 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开.
1002 由于协议错误而中断连接.
1003 由于接收到不允许的数据类型而断开连接 (如仅接收文本数据的终端接收到了二进制数据).
1004 保留. 其意义可能会在未来定义.
1005 保留. 表示没有收到预期的状态码.
1006 保留. 用于期望收到状态码时连接非正常关闭 (也就是说, 没有发送关闭帧).
1007 由于收到了格式不符的数据而断开连接 (如文本消息中包含了非 UTF-8 数据).
1008 由于收到不符合约定的数据而断开连接. 这是一个通用状态码, 用于不适合使用 1003 和 1009 状态码的场景.
1009 由于收到过大的数据帧而断开连接.
1010 客户端期望服务器商定一个或多个拓展, 但服务器没有处理, 因此客户端断开连接.
1011 客户端由于遇到没有预料的情况阻止其完成请求, 因此服务端断开连接.
1012 服务器由于重启而断开连接.
1013 服务器由于临时原因断开连接, 如服务器过载因此断开一部分客户端连接.
1014 由 WebSocket标准保留以便未来使用.
1015 保留. 表示连接由于无法完成 TLS 握手而关闭 (例如无法验证服务器证书).
1016–1999 由 WebSocket标准保留以便未来使用.
2000–2999 由 WebSocket拓展保留使用.
ps: 其他注意事项
如果你的服务所用的协议是HTTPS的,那么使用的WebSocket协议也必须是wss, 而不能是ws
参考资料链接:
https://www.cnblogs.com/scott-j/p/9306197.html
https://segmentfault.com/a/1190000014582485?utm_source=tag-newest
https://blog.csdn.net/qq_39186346/article/details/81941664
Mac电脑通过nvm来管理node版本
碰到node的依赖包加载问题,尝试升级node版本解决,
升级系统node的时候,老是忘记自己用的node版本管理器,做个记录。
zhujin@MacBook-Pro ~ % nvm list
v0.10.32
v6.1.0
v7.10.0
v8.7.0
v8.10.0
v9.4.0
v12.4.0
-> v13.0.1
system
default -> 13.0.1 (-> v13.0.1)
node -> stable (-> v13.0.1) (default)
stable -> 13.0 (-> v13.0.1) (default)
unstable -> N/A (default)
iojs -> iojs- (-> system) (default)
lts/* -> lts/erbium (-> N/A)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.22.0 (-> N/A)
lts/erbium -> v12.18.3 (-> N/A)
升级命令 nvm install stable
zhujin@MacBook-Pro ~ % nvm install stable
Downloading and installing node v14.7.0...
Downloading https://nodejs.org/dist/v14.7.0/node-v14.7.0-darwin-x64.tar.xz...
################################################################################################################# 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v14.7.0 (npm v6.14.7)
然后当前的终端已经版本OK了,然后你会发现每次打开终端,都会自动把版本变回去,所以最后需要设置默认node版本:
nvm alias default 14.7.0
3dmax 用了2个材质贴图,发生了贴图错位、透视和重叠
3dmax 用了2个材质贴图,发生了透视和重叠,2个贴图一个是不透明的,一个是透明的,只要透明的加上,就部分透视了。
一开始以为是法线或者是图片通道的问题,改啊弄啊怎么都不能顺利解决。
接近花了一整天之后,终于发现了解决方法,shift+f3就解决了,原因未知,特此记录。
关于 “SetDestination can only be called on an active agent that has been placed on a NavMesh” 真正的解决方案
最近碰到了 "SetDestination can only be called on an active agent that has been placed on a NavMesh" 的问题,关键点不在于不会用Navmesh,而是真的他就这么报错了。
找了很多办法,耗时1天,终于在国外论坛上看到真正的解决方案了。
常规解决方案:
- 检查场景是否烘焙。
- 检查目标或自己是否位于navmesh上,不是在半空。
- 尝试使用NavMesh.SamplePosition方法。
GameObject go = new GameObject("Target");
Vector3 sourcePostion = new Vector3( 100, 20, 100 );//The position you want to place your agent
NavMeshHit closestHit;
if( NavMesh.SamplePosition( sourcePostion, out closestHit, 500, 1 ) ){
go.transform.position = closestHit.position;
go.AddComponent<NavMeshAgent>();
//TODO
}
else{
Debug.Log("...");
}
如果常规方法没解决,且寻路是时好时坏,对象和自己均是代码生成的,那八九不离十肯定碰到了我碰到的问题。
解决方法很简单:
在prefab里就添加了NavMeshAgent组件的,把他勾掉,然后在物体的start里面agent.enabled = true;
如果是在awake代码生成的,AddComponent后把enabled设置成false,然后在物体的start里面agent.enabled = true;
示例:
void Awake () {
// 添加寻路组件
agent = this.gameObject.AddComponent<NavMeshAgent> ();
agent.speed = 3.5f;
agent.enabled = false;
// ...
}
// Use this for initialization
void Start () {
agent.enabled = true;
}
Laravel在使用model的时候,总是会自动加S,导致错误的解决方法
很简单的处理方式,只要在model里指定表名就可以了。
class XX extend Model{
public $table='tableName';
//...
}